1 /*
2 * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
3 *
4 * Use is subject to license terms.
5 */
6 /*
7 * Copyright (c) 2012, OmniTI Computer Consulting, Inc. All rights reserved.
8 */
9 /*
10 * Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
11 * project 2000.
12 */
13 /*
14 * ====================================================================
15 * Copyright (c) 2000-2004 The OpenSSL Project. All rights reserved.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions
19 * are met:
20 *
21 * 1. Redistributions of source code must retain the above copyright
22 * notice, this list of conditions and the following disclaimer.
23 *
24 * 2. Redistributions in binary form must reproduce the above copyright
25 * notice, this list of conditions and the following disclaimer in
26 * the documentation and/or other materials provided with the
27 * distribution.
28 *
29 * 3. All advertising materials mentioning features or use of this
30 * software must display the following acknowledgment:
31 * "This product includes software developed by the OpenSSL Project
32 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
33 *
34 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
35 * endorse or promote products derived from this software without
36 * prior written permission. For written permission, please contact
37 * licensing@OpenSSL.org.
38 *
39 * 5. Products derived from this software may not be called "OpenSSL"
40 * nor may "OpenSSL" appear in their names without prior written
41 * permission of the OpenSSL Project.
42 *
43 * 6. Redistributions of any form whatsoever must retain the following
44 * acknowledgment:
45 * "This product includes software developed by the OpenSSL Project
46 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
47 *
48 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
49 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
51 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
52 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
53 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
54 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
55 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
57 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
58 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
59 * OF THE POSSIBILITY OF SUCH DAMAGE.
60 * ====================================================================
61 *
62 * This product includes cryptographic software written by Eric Young
63 * (eay@cryptsoft.com). This product includes software written by Tim
64 * Hudson (tjh@cryptsoft.com).
65 *
66 */
67
68 #include <stdlib.h>
69 #include <kmfapiP.h>
70 #include <ber_der.h>
71 #include <fcntl.h>
72 #include <sys/stat.h>
73 #include <dirent.h>
74 #include <cryptoutil.h>
75 #include <synch.h>
76 #include <thread.h>
77
78 /* OPENSSL related headers */
79 #include <openssl/bio.h>
80 #include <openssl/bn.h>
81 #include <openssl/asn1.h>
82 #include <openssl/err.h>
83 #include <openssl/bn.h>
84 #include <openssl/x509.h>
85 #include <openssl/rsa.h>
86 #include <openssl/dsa.h>
87 #include <openssl/x509v3.h>
88 #include <openssl/objects.h>
89 #include <openssl/pem.h>
90 #include <openssl/pkcs12.h>
91 #include <openssl/ocsp.h>
92 #include <openssl/des.h>
93 #include <openssl/rand.h>
94
95 #define PRINT_ANY_EXTENSION (\
96 KMF_X509_EXT_KEY_USAGE |\
97 KMF_X509_EXT_CERT_POLICIES |\
98 KMF_X509_EXT_SUBJALTNAME |\
99 KMF_X509_EXT_BASIC_CONSTRAINTS |\
100 KMF_X509_EXT_NAME_CONSTRAINTS |\
101 KMF_X509_EXT_POLICY_CONSTRAINTS |\
102 KMF_X509_EXT_EXT_KEY_USAGE |\
103 KMF_X509_EXT_INHIBIT_ANY_POLICY |\
104 KMF_X509_EXT_AUTH_KEY_ID |\
105 KMF_X509_EXT_SUBJ_KEY_ID |\
106 KMF_X509_EXT_POLICY_MAPPING)
107
108 static uchar_t P[] = { 0x00, 0x8d, 0xf2, 0xa4, 0x94, 0x49, 0x22, 0x76,
109 0xaa, 0x3d, 0x25, 0x75, 0x9b, 0xb0, 0x68, 0x69,
110 0xcb, 0xea, 0xc0, 0xd8, 0x3a, 0xfb, 0x8d, 0x0c,
111 0xf7, 0xcb, 0xb8, 0x32, 0x4f, 0x0d, 0x78, 0x82,
112 0xe5, 0xd0, 0x76, 0x2f, 0xc5, 0xb7, 0x21, 0x0e,
113 0xaf, 0xc2, 0xe9, 0xad, 0xac, 0x32, 0xab, 0x7a,
114 0xac, 0x49, 0x69, 0x3d, 0xfb, 0xf8, 0x37, 0x24,
115 0xc2, 0xec, 0x07, 0x36, 0xee, 0x31, 0xc8, 0x02,
116 0x91 };
117
118 static uchar_t Q[] = { 0x00, 0xc7, 0x73, 0x21, 0x8c, 0x73, 0x7e, 0xc8,
119 0xee, 0x99, 0x3b, 0x4f, 0x2d, 0xed, 0x30, 0xf4,
120 0x8e, 0xda, 0xce, 0x91, 0x5f };
121
122 static uchar_t G[] = { 0x00, 0x62, 0x6d, 0x02, 0x78, 0x39, 0xea, 0x0a,
123 0x13, 0x41, 0x31, 0x63, 0xa5, 0x5b, 0x4c, 0xb5,
124 0x00, 0x29, 0x9d, 0x55, 0x22, 0x95, 0x6c, 0xef,
125 0xcb, 0x3b, 0xff, 0x10, 0xf3, 0x99, 0xce, 0x2c,
126 0x2e, 0x71, 0xcb, 0x9d, 0xe5, 0xfa, 0x24, 0xba,
127 0xbf, 0x58, 0xe5, 0xb7, 0x95, 0x21, 0x92, 0x5c,
128 0x9c, 0xc4, 0x2e, 0x9f, 0x6f, 0x46, 0x4b, 0x08,
129 0x8c, 0xc5, 0x72, 0xaf, 0x53, 0xe6, 0xd7, 0x88,
130 0x02 };
131
132 #define SET_ERROR(h, c) h->lasterr.kstype = KMF_KEYSTORE_OPENSSL; \
133 h->lasterr.errcode = c;
134
135 #define SET_SYS_ERROR(h, c) h->lasterr.kstype = -1; h->lasterr.errcode = c;
136
137 /*
138 * Declare some new macros for managing stacks of EVP_PKEYS, similar to
139 * what wanboot did.
140 */
141 DECLARE_STACK_OF(EVP_PKEY)
142
143 #define sk_EVP_PKEY_new_null() SKM_sk_new_null(EVP_PKEY)
144 #define sk_EVP_PKEY_free(st) SKM_sk_free(EVP_PKEY, (st))
145 #define sk_EVP_PKEY_num(st) SKM_sk_num(EVP_PKEY, (st))
146 #define sk_EVP_PKEY_value(st, i) SKM_sk_value(EVP_PKEY, (st), (i))
147 #define sk_EVP_PKEY_push(st, val) SKM_sk_push(EVP_PKEY, (st), (val))
148 #define sk_EVP_PKEY_pop_free(st, free_func) SKM_sk_pop_free(EVP_PKEY, (st), \
149 (free_func))
150
151 mutex_t init_lock = DEFAULTMUTEX;
152 static int ssl_initialized = 0;
153 static BIO *bio_err = NULL;
154
155 static int
156 test_for_file(char *, mode_t);
157 static KMF_RETURN
158 openssl_parse_bag(PKCS12_SAFEBAG *, char *, int,
159 STACK_OF(EVP_PKEY) *, STACK_OF(X509) *);
160
161 static KMF_RETURN
162 local_export_pk12(KMF_HANDLE_T, KMF_CREDENTIAL *, int, KMF_X509_DER_CERT *,
163 int, KMF_KEY_HANDLE *, char *);
164
165 static KMF_RETURN set_pkey_attrib(EVP_PKEY *, ASN1_TYPE *, int);
166
167 static KMF_RETURN
168 extract_pem(KMF_HANDLE *, char *, char *, KMF_BIGINT *, char *,
169 CK_UTF8CHAR *, CK_ULONG, EVP_PKEY **, KMF_DATA **, int *);
170
171 static KMF_RETURN
172 kmf_load_cert(KMF_HANDLE *, char *, char *, KMF_BIGINT *, KMF_CERT_VALIDITY,
173 char *, KMF_DATA *);
174
175 static KMF_RETURN
176 load_certs(KMF_HANDLE *, char *, char *, KMF_BIGINT *, KMF_CERT_VALIDITY,
177 char *, KMF_DATA **, uint32_t *);
178
179 static KMF_RETURN
180 sslBN2KMFBN(BIGNUM *, KMF_BIGINT *);
181
182 static EVP_PKEY *
183 ImportRawRSAKey(KMF_RAW_RSA_KEY *);
184
185 static KMF_RETURN
186 convertToRawKey(EVP_PKEY *, KMF_RAW_KEY_DATA *);
187
188 KMF_RETURN
189 OpenSSL_FindCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
190
191 void
192 OpenSSL_FreeKMFCert(KMF_HANDLE_T, KMF_X509_DER_CERT *);
193
194 KMF_RETURN
195 OpenSSL_StoreCert(KMF_HANDLE_T handle, int, KMF_ATTRIBUTE *);
196
197 KMF_RETURN
198 OpenSSL_DeleteCert(KMF_HANDLE_T handle, int, KMF_ATTRIBUTE *);
199
200 KMF_RETURN
201 OpenSSL_CreateKeypair(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
202
203 KMF_RETURN
204 OpenSSL_StoreKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
205
206 KMF_RETURN
207 OpenSSL_EncodePubKeyData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_DATA *);
208
209 KMF_RETURN
210 OpenSSL_SignData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *,
211 KMF_DATA *, KMF_DATA *);
212
213 KMF_RETURN
214 OpenSSL_DeleteKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
215
216 KMF_RETURN
217 OpenSSL_ImportCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
218
219 KMF_RETURN
220 OpenSSL_DeleteCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
221
222 KMF_RETURN
223 OpenSSL_ListCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
224
225 KMF_RETURN
226 OpenSSL_FindCertInCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
227
228 KMF_RETURN
229 OpenSSL_CertGetPrintable(KMF_HANDLE_T, const KMF_DATA *,
230 KMF_PRINTABLE_ITEM, char *);
231
232 KMF_RETURN
233 OpenSSL_GetErrorString(KMF_HANDLE_T, char **);
234
235 KMF_RETURN
236 OpenSSL_FindPrikeyByCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
237
238 KMF_RETURN
239 OpenSSL_DecryptData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *,
240 KMF_DATA *, KMF_DATA *);
241
242 KMF_RETURN
243 OpenSSL_CreateOCSPRequest(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
244
245 KMF_RETURN
246 OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
247
248 KMF_RETURN
249 OpenSSL_FindKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
250
251 KMF_RETURN
252 OpenSSL_ExportPK12(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
253
254 KMF_RETURN
255 OpenSSL_CreateSymKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
256
257 KMF_RETURN
258 OpenSSL_GetSymKeyValue(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_RAW_SYM_KEY *);
259
260 KMF_RETURN
261 OpenSSL_VerifyCRLFile(KMF_HANDLE_T, char *, KMF_DATA *);
262
263 KMF_RETURN
264 OpenSSL_CheckCRLDate(KMF_HANDLE_T, char *);
265
266 static
267 KMF_PLUGIN_FUNCLIST openssl_plugin_table =
268 {
269 1, /* Version */
270 NULL, /* ConfigureKeystore */
271 OpenSSL_FindCert,
272 OpenSSL_FreeKMFCert,
273 OpenSSL_StoreCert,
274 NULL, /* ImportCert */
275 OpenSSL_ImportCRL,
276 OpenSSL_DeleteCert,
277 OpenSSL_DeleteCRL,
278 OpenSSL_CreateKeypair,
279 OpenSSL_FindKey,
280 OpenSSL_EncodePubKeyData,
281 OpenSSL_SignData,
282 OpenSSL_DeleteKey,
283 OpenSSL_ListCRL,
284 NULL, /* FindCRL */
285 OpenSSL_FindCertInCRL,
286 OpenSSL_GetErrorString,
287 OpenSSL_FindPrikeyByCert,
288 OpenSSL_DecryptData,
289 OpenSSL_ExportPK12,
290 OpenSSL_CreateSymKey,
291 OpenSSL_GetSymKeyValue,
292 NULL, /* SetTokenPin */
293 OpenSSL_StoreKey,
294 NULL /* Finalize */
295 };
296
297 static mutex_t *lock_cs;
298 static long *lock_count;
299
300 static void
301 /* ARGSUSED1 */
302 locking_cb(int mode, int type, char *file, int line)
303 {
304 if (mode & CRYPTO_LOCK) {
305 (void) mutex_lock(&(lock_cs[type]));
306 lock_count[type]++;
307 } else {
308 (void) mutex_unlock(&(lock_cs[type]));
309 }
310 }
311
312 static unsigned long
313 thread_id()
314 {
315 return ((unsigned long)thr_self());
316 }
317
318 KMF_PLUGIN_FUNCLIST *
319 KMF_Plugin_Initialize()
320 {
321 int i;
322
323 (void) mutex_lock(&init_lock);
324 if (!ssl_initialized) {
325 /*
326 * Add support for extension OIDs that are not yet in the
327 * openssl default set.
328 */
329 (void) OBJ_create("2.5.29.30", "nameConstraints",
330 "X509v3 Name Constraints");
331 (void) OBJ_create("2.5.29.33", "policyMappings",
332 "X509v3 Policy Mappings");
333 (void) OBJ_create("2.5.29.36", "policyConstraints",
334 "X509v3 Policy Constraints");
335 (void) OBJ_create("2.5.29.46", "freshestCRL",
336 "X509v3 Freshest CRL");
337 (void) OBJ_create("2.5.29.54", "inhibitAnyPolicy",
338 "X509v3 Inhibit Any-Policy");
339 /*
340 * Set up for thread-safe operation.
341 */
342 lock_cs = OPENSSL_malloc(CRYPTO_num_locks() * sizeof (mutex_t));
343 if (lock_cs == NULL) {
344 (void) mutex_unlock(&init_lock);
345 return (NULL);
346 }
347
348 lock_count = OPENSSL_malloc(CRYPTO_num_locks() * sizeof (long));
349 if (lock_count == NULL) {
350 OPENSSL_free(lock_cs);
351 (void) mutex_unlock(&init_lock);
352 return (NULL);
353 }
354
355 for (i = 0; i < CRYPTO_num_locks(); i++) {
356 lock_count[i] = 0;
357 (void) mutex_init(&lock_cs[i], USYNC_THREAD, NULL);
358 }
359
360 CRYPTO_set_id_callback((unsigned long (*)())thread_id);
361 if (CRYPTO_get_locking_callback() == NULL)
362 CRYPTO_set_locking_callback((void (*)())locking_cb);
363
364 OpenSSL_add_all_algorithms();
365
366 /* Enable error strings for reporting */
367 ERR_load_crypto_strings();
368
369 ssl_initialized = 1;
370 }
371 (void) mutex_unlock(&init_lock);
372
373 return (&openssl_plugin_table);
374 }
375 /*
376 * Convert an SSL DN to a KMF DN.
377 */
378 static KMF_RETURN
379 get_x509_dn(X509_NAME *sslDN, KMF_X509_NAME *kmfDN)
380 {
381 KMF_DATA derdata;
382 KMF_RETURN rv = KMF_OK;
383 uchar_t *tmp;
384
385 /* Convert to raw DER format */
386 derdata.Length = i2d_X509_NAME(sslDN, NULL);
387 if ((tmp = derdata.Data = (uchar_t *)OPENSSL_malloc(derdata.Length))
388 == NULL) {
389 return (KMF_ERR_MEMORY);
390 }
391 (void) i2d_X509_NAME(sslDN, &tmp);
392
393 /* Decode to KMF format */
394 rv = DerDecodeName(&derdata, kmfDN);
395 if (rv != KMF_OK) {
396 rv = KMF_ERR_BAD_CERT_FORMAT;
397 }
398 OPENSSL_free(derdata.Data);
399
400 return (rv);
401 }
402
403 int
404 isdir(char *path)
405 {
406 struct stat s;
407
408 if (stat(path, &s) == -1)
409 return (0);
410
411 return ((s.st_mode & S_IFMT) == S_IFDIR);
412 }
413
414 static KMF_RETURN
415 ssl_cert2KMFDATA(KMF_HANDLE *kmfh, X509 *x509cert, KMF_DATA *cert)
416 {
417 KMF_RETURN rv = KMF_OK;
418 unsigned char *buf = NULL, *p;
419 int len;
420
421 /*
422 * Convert the X509 internal struct to DER encoded data
423 */
424 if ((len = i2d_X509(x509cert, NULL)) < 0) {
425 SET_ERROR(kmfh, ERR_get_error());
426 rv = KMF_ERR_BAD_CERT_FORMAT;
427 goto cleanup;
428 }
429 if ((buf = malloc(len)) == NULL) {
430 SET_SYS_ERROR(kmfh, errno);
431 rv = KMF_ERR_MEMORY;
432 goto cleanup;
433 }
434
435 /*
436 * i2d_X509 will increment the buf pointer so that we need to
437 * save it.
438 */
439 p = buf;
440 if ((len = i2d_X509(x509cert, &p)) < 0) {
441 SET_ERROR(kmfh, ERR_get_error());
442 free(buf);
443 rv = KMF_ERR_BAD_CERT_FORMAT;
444 goto cleanup;
445 }
446
447 /* caller's responsibility to free it */
448 cert->Data = buf;
449 cert->Length = len;
450
451 cleanup:
452 if (rv != KMF_OK) {
453 if (buf)
454 free(buf);
455 cert->Data = NULL;
456 cert->Length = 0;
457 }
458
459 return (rv);
460 }
461
462
463 static KMF_RETURN
464 check_cert(X509 *xcert, char *issuer, char *subject, KMF_BIGINT *serial,
465 boolean_t *match)
466 {
467 KMF_RETURN rv = KMF_OK;
468 boolean_t findIssuer = FALSE;
469 boolean_t findSubject = FALSE;
470 boolean_t findSerial = FALSE;
471 KMF_X509_NAME issuerDN, subjectDN;
472 KMF_X509_NAME certIssuerDN, certSubjectDN;
473
474 *match = FALSE;
475 if (xcert == NULL) {
476 return (KMF_ERR_BAD_PARAMETER);
477 }
478
479 (void) memset(&issuerDN, 0, sizeof (KMF_X509_NAME));
480 (void) memset(&subjectDN, 0, sizeof (KMF_X509_NAME));
481 (void) memset(&certIssuerDN, 0, sizeof (KMF_X509_NAME));
482 (void) memset(&certSubjectDN, 0, sizeof (KMF_X509_NAME));
483
484 if (issuer != NULL && strlen(issuer)) {
485 rv = kmf_dn_parser(issuer, &issuerDN);
486 if (rv != KMF_OK)
487 return (KMF_ERR_BAD_PARAMETER);
488
489 rv = get_x509_dn(xcert->cert_info->issuer, &certIssuerDN);
490 if (rv != KMF_OK) {
491 kmf_free_dn(&issuerDN);
492 return (KMF_ERR_BAD_PARAMETER);
493 }
494
495 findIssuer = TRUE;
496 }
497 if (subject != NULL && strlen(subject)) {
498 rv = kmf_dn_parser(subject, &subjectDN);
499 if (rv != KMF_OK) {
500 rv = KMF_ERR_BAD_PARAMETER;
501 goto cleanup;
502 }
503
504 rv = get_x509_dn(xcert->cert_info->subject, &certSubjectDN);
505 if (rv != KMF_OK) {
506 rv = KMF_ERR_BAD_PARAMETER;
507 goto cleanup;
508 }
509 findSubject = TRUE;
510 }
511 if (serial != NULL && serial->val != NULL)
512 findSerial = TRUE;
513
514 if (findSerial) {
515 BIGNUM *bn;
516
517 /* Comparing BIGNUMs is a pain! */
518 bn = ASN1_INTEGER_to_BN(xcert->cert_info->serialNumber, NULL);
519 if (bn != NULL) {
520 int bnlen = BN_num_bytes(bn);
521
522 if (bnlen == serial->len) {
523 uchar_t *a = malloc(bnlen);
524 if (a == NULL) {
525 rv = KMF_ERR_MEMORY;
526 BN_free(bn);
527 goto cleanup;
528 }
529 bnlen = BN_bn2bin(bn, a);
530 *match = (memcmp(a, serial->val, serial->len) ==
531 0);
532 rv = KMF_OK;
533 free(a);
534 }
535 BN_free(bn);
536 if (!(*match))
537 goto cleanup;
538 } else {
539 rv = KMF_OK;
540 goto cleanup;
541 }
542 }
543 if (findIssuer) {
544 *match = (kmf_compare_rdns(&issuerDN, &certIssuerDN) == 0);
545 if ((*match) == B_FALSE) {
546 /* stop checking and bail */
547 rv = KMF_OK;
548 goto cleanup;
549 }
550 }
551 if (findSubject) {
552 *match = (kmf_compare_rdns(&subjectDN, &certSubjectDN) == 0);
553 if ((*match) == B_FALSE) {
554 /* stop checking and bail */
555 rv = KMF_OK;
556 goto cleanup;
557 }
558 }
559
560 *match = TRUE;
561 cleanup:
562 if (findIssuer) {
563 kmf_free_dn(&issuerDN);
564 kmf_free_dn(&certIssuerDN);
565 }
566 if (findSubject) {
567 kmf_free_dn(&subjectDN);
568 kmf_free_dn(&certSubjectDN);
569 }
570
571 return (rv);
572 }
573
574
575 /*
576 * This function loads a certificate file into an X509 data structure, and
577 * checks if its issuer, subject or the serial number matches with those
578 * values. If it matches, then return the X509 data structure.
579 */
580 static KMF_RETURN
581 load_X509cert(KMF_HANDLE *kmfh,
582 char *issuer, char *subject, KMF_BIGINT *serial,
583 char *pathname, X509 **outcert)
584 {
585 KMF_RETURN rv = KMF_OK;
586 X509 *xcert = NULL;
587 BIO *bcert = NULL;
588 boolean_t match = FALSE;
589 KMF_ENCODE_FORMAT format;
590
591 /*
592 * auto-detect the file format, regardless of what
593 * the 'format' parameters in the params say.
594 */
595 rv = kmf_get_file_format(pathname, &format);
596 if (rv != KMF_OK) {
597 if (rv == KMF_ERR_OPEN_FILE)
598 rv = KMF_ERR_CERT_NOT_FOUND;
599 return (rv);
600 }
601
602 /* Not ASN1(DER) format */
603 if ((bcert = BIO_new_file(pathname, "rb")) == NULL) {
604 SET_ERROR(kmfh, ERR_get_error());
605 rv = KMF_ERR_OPEN_FILE;
606 goto cleanup;
607 }
608
609 if (format == KMF_FORMAT_PEM)
610 xcert = PEM_read_bio_X509_AUX(bcert, NULL, NULL, NULL);
611 else if (format == KMF_FORMAT_ASN1)
612 xcert = d2i_X509_bio(bcert, NULL);
613 else if (format == KMF_FORMAT_PKCS12) {
614 PKCS12 *p12 = d2i_PKCS12_bio(bcert, NULL);
615 if (p12 != NULL) {
616 (void) PKCS12_parse(p12, NULL, NULL, &xcert, NULL);
617 PKCS12_free(p12);
618 p12 = NULL;
619 } else {
620 SET_ERROR(kmfh, ERR_get_error());
621 rv = KMF_ERR_BAD_CERT_FORMAT;
622 }
623 } else {
624 rv = KMF_ERR_BAD_PARAMETER;
625 goto cleanup;
626 }
627
628 if (xcert == NULL) {
629 SET_ERROR(kmfh, ERR_get_error());
630 rv = KMF_ERR_BAD_CERT_FORMAT;
631 goto cleanup;
632 }
633
634 if (check_cert(xcert, issuer, subject, serial, &match) != KMF_OK ||
635 match == FALSE) {
636 rv = KMF_ERR_CERT_NOT_FOUND;
637 goto cleanup;
638 }
639
640 if (outcert != NULL) {
641 *outcert = xcert;
642 }
643
644 cleanup:
645 if (bcert != NULL) (void) BIO_free(bcert);
646 if (rv != KMF_OK && xcert != NULL)
647 X509_free(xcert);
648
649 return (rv);
650 }
651
652 static int
653 datacmp(const void *a, const void *b)
654 {
655 KMF_DATA *adata = (KMF_DATA *)a;
656 KMF_DATA *bdata = (KMF_DATA *)b;
657 if (adata->Length > bdata->Length)
658 return (-1);
659 if (adata->Length < bdata->Length)
660 return (1);
661 return (0);
662 }
663
664 static KMF_RETURN
665 load_certs(KMF_HANDLE *kmfh, char *issuer, char *subject, KMF_BIGINT *serial,
666 KMF_CERT_VALIDITY validity, char *pathname,
667 KMF_DATA **certlist, uint32_t *numcerts)
668 {
669 KMF_RETURN rv = KMF_OK;
670 int i;
671 KMF_DATA *certs = NULL;
672 int nc = 0;
673 int hits = 0;
674 KMF_ENCODE_FORMAT format;
675
676 rv = kmf_get_file_format(pathname, &format);
677 if (rv != KMF_OK) {
678 if (rv == KMF_ERR_OPEN_FILE)
679 rv = KMF_ERR_CERT_NOT_FOUND;
680 return (rv);
681 }
682 if (format == KMF_FORMAT_ASN1) {
683 /* load a single certificate */
684 certs = (KMF_DATA *)malloc(sizeof (KMF_DATA));
685 if (certs == NULL)
686 return (KMF_ERR_MEMORY);
687 certs->Data = NULL;
688 certs->Length = 0;
689 rv = kmf_load_cert(kmfh, issuer, subject, serial, validity,
690 pathname, certs);
691 if (rv == KMF_OK) {
692 *certlist = certs;
693 *numcerts = 1;
694 } else {
695 kmf_free_data(certs);
696 free(certs);
697 certs = NULL;
698 }
699 return (rv);
700 } else if (format == KMF_FORMAT_PKCS12) {
701 /* We need a credential to access a PKCS#12 file */
702 rv = KMF_ERR_BAD_CERT_FORMAT;
703 } else if (format == KMF_FORMAT_PEM ||
704 format != KMF_FORMAT_PEM_KEYPAIR) {
705
706 /* This function only works on PEM files */
707 rv = extract_pem(kmfh, issuer, subject, serial, pathname,
708 (uchar_t *)NULL, 0, NULL, &certs, &nc);
709 } else {
710 return (KMF_ERR_ENCODING);
711 }
712
713 if (rv != KMF_OK)
714 return (rv);
715
716 for (i = 0; i < nc; i++) {
717 if (validity == KMF_NONEXPIRED_CERTS) {
718 rv = kmf_check_cert_date(kmfh, &certs[i]);
719 } else if (validity == KMF_EXPIRED_CERTS) {
720 rv = kmf_check_cert_date(kmfh, &certs[i]);
721 if (rv == KMF_OK)
722 rv = KMF_ERR_CERT_NOT_FOUND;
723 if (rv == KMF_ERR_VALIDITY_PERIOD)
724 rv = KMF_OK;
725 }
726 if (rv != KMF_OK) {
727 /* Remove this cert from the list by clearing it. */
728 kmf_free_data(&certs[i]);
729 } else {
730 hits++; /* count valid certs found */
731 }
732 rv = KMF_OK;
733 }
734 if (rv == KMF_OK && hits > 0) {
735 /*
736 * Sort the list of certs by length to put the cleared ones
737 * at the end so they don't get accessed by the caller.
738 */
739 qsort((void *)certs, nc, sizeof (KMF_DATA), datacmp);
740 *certlist = certs;
741
742 /* since we sorted the list, just return the number of hits */
743 *numcerts = hits;
744 } else {
745 if (rv == KMF_OK && hits == 0)
746 rv = KMF_ERR_CERT_NOT_FOUND;
747 if (certs != NULL) {
748 free(certs);
749 certs = NULL;
750 }
751 }
752 return (rv);
753 }
754
755 static KMF_RETURN
756 kmf_load_cert(KMF_HANDLE *kmfh,
757 char *issuer, char *subject, KMF_BIGINT *serial,
758 KMF_CERT_VALIDITY validity,
759 char *pathname,
760 KMF_DATA *cert)
761 {
762 KMF_RETURN rv = KMF_OK;
763 X509 *x509cert = NULL;
764
765 rv = load_X509cert(kmfh, issuer, subject, serial, pathname, &x509cert);
766 if (rv == KMF_OK && x509cert != NULL && cert != NULL) {
767 rv = ssl_cert2KMFDATA(kmfh, x509cert, cert);
768 if (rv != KMF_OK) {
769 goto cleanup;
770 }
771 if (validity == KMF_NONEXPIRED_CERTS) {
772 rv = kmf_check_cert_date(kmfh, cert);
773 } else if (validity == KMF_EXPIRED_CERTS) {
774 rv = kmf_check_cert_date(kmfh, cert);
775 if (rv == KMF_OK) {
776 /*
777 * This is a valid cert so skip it.
778 */
779 rv = KMF_ERR_CERT_NOT_FOUND;
780 }
781 if (rv == KMF_ERR_VALIDITY_PERIOD) {
782 /*
783 * We want to return success when we
784 * find an invalid cert.
785 */
786 rv = KMF_OK;
787 goto cleanup;
788 }
789 }
790 }
791 cleanup:
792 if (x509cert != NULL)
793 X509_free(x509cert);
794
795 return (rv);
796 }
797
798 static KMF_RETURN
799 readAltFormatPrivateKey(KMF_DATA *filedata, EVP_PKEY **pkey)
800 {
801 KMF_RETURN ret = KMF_OK;
802 KMF_RAW_RSA_KEY rsa;
803 BerElement *asn1 = NULL;
804 BerValue filebuf;
805 BerValue OID = { NULL, 0 };
806 BerValue *Mod = NULL, *PubExp = NULL;
807 BerValue *PriExp = NULL, *Prime1 = NULL, *Prime2 = NULL;
808 BerValue *Coef = NULL;
809 BIGNUM *D = NULL, *P = NULL, *Q = NULL, *COEF = NULL;
810 BIGNUM *Exp1 = NULL, *Exp2 = NULL, *pminus1 = NULL;
811 BIGNUM *qminus1 = NULL;
812 BN_CTX *ctx = NULL;
813
814 *pkey = NULL;
815
816 filebuf.bv_val = (char *)filedata->Data;
817 filebuf.bv_len = filedata->Length;
818
819 asn1 = kmfder_init(&filebuf);
820 if (asn1 == NULL) {
821 ret = KMF_ERR_MEMORY;
822 goto out;
823 }
824
825 if (kmfber_scanf(asn1, "{{Dn{IIIIII}}}",
826 &OID, &Mod, &PubExp, &PriExp, &Prime1,
827 &Prime2, &Coef) == -1) {
828 ret = KMF_ERR_ENCODING;
829 goto out;
830 }
831
832 /*
833 * We have to derive the 2 Exponents using Bignumber math.
834 * Exp1 = PriExp mod (Prime1 - 1)
835 * Exp2 = PriExp mod (Prime2 - 1)
836 */
837
838 /* D = PrivateExponent */
839 D = BN_bin2bn((const uchar_t *)PriExp->bv_val, PriExp->bv_len, D);
840 if (D == NULL) {
841 ret = KMF_ERR_MEMORY;
842 goto out;
843 }
844
845 /* P = Prime1 (first prime factor of Modulus) */
846 P = BN_bin2bn((const uchar_t *)Prime1->bv_val, Prime1->bv_len, P);
847 if (D == NULL) {
848 ret = KMF_ERR_MEMORY;
849 goto out;
850 }
851
852 /* Q = Prime2 (second prime factor of Modulus) */
853 Q = BN_bin2bn((const uchar_t *)Prime2->bv_val, Prime2->bv_len, Q);
854
855 if ((ctx = BN_CTX_new()) == NULL) {
856 ret = KMF_ERR_MEMORY;
857 goto out;
858 }
859
860 /* Compute (P - 1) */
861 pminus1 = BN_new();
862 (void) BN_sub(pminus1, P, BN_value_one());
863
864 /* Exponent1 = D mod (P - 1) */
865 Exp1 = BN_new();
866 (void) BN_mod(Exp1, D, pminus1, ctx);
867
868 /* Compute (Q - 1) */
869 qminus1 = BN_new();
870 (void) BN_sub(qminus1, Q, BN_value_one());
871
872 /* Exponent2 = D mod (Q - 1) */
873 Exp2 = BN_new();
874 (void) BN_mod(Exp2, D, qminus1, ctx);
875
876 /* Coef = (Inverse Q) mod P */
877 COEF = BN_new();
878 (void) BN_mod_inverse(COEF, Q, P, ctx);
879
880 /* Convert back to KMF format */
881 (void) memset(&rsa, 0, sizeof (rsa));
882
883 if ((ret = sslBN2KMFBN(Exp1, &rsa.exp1)) != KMF_OK)
884 goto out;
885 if ((ret = sslBN2KMFBN(Exp2, &rsa.exp2)) != KMF_OK)
886 goto out;
887 if ((ret = sslBN2KMFBN(COEF, &rsa.coef)) != KMF_OK)
888 goto out;
889
890 rsa.mod.val = (uchar_t *)Mod->bv_val;
891 rsa.mod.len = Mod->bv_len;
892
893 rsa.pubexp.val = (uchar_t *)PubExp->bv_val;
894 rsa.pubexp.len = PubExp->bv_len;
895
896 rsa.priexp.val = (uchar_t *)PriExp->bv_val;
897 rsa.priexp.len = PriExp->bv_len;
898
899 rsa.prime1.val = (uchar_t *)Prime1->bv_val;
900 rsa.prime1.len = Prime1->bv_len;
901
902 rsa.prime2.val = (uchar_t *)Prime2->bv_val;
903 rsa.prime2.len = Prime2->bv_len;
904
905 *pkey = ImportRawRSAKey(&rsa);
906 out:
907 if (asn1 != NULL)
908 kmfber_free(asn1, 1);
909
910 if (OID.bv_val) {
911 free(OID.bv_val);
912 }
913 if (PriExp)
914 free(PriExp);
915
916 if (Mod)
917 free(Mod);
918
919 if (PubExp)
920 free(PubExp);
921
922 if (Coef) {
923 (void) memset(Coef->bv_val, 0, Coef->bv_len);
924 free(Coef->bv_val);
925 free(Coef);
926 }
927 if (Prime1)
928 free(Prime1);
929 if (Prime2)
930 free(Prime2);
931
932 if (ctx != NULL)
933 BN_CTX_free(ctx);
934
935 if (D)
936 BN_clear_free(D);
937 if (P)
938 BN_clear_free(P);
939 if (Q)
940 BN_clear_free(Q);
941 if (pminus1)
942 BN_clear_free(pminus1);
943 if (qminus1)
944 BN_clear_free(qminus1);
945 if (Exp1)
946 BN_clear_free(Exp1);
947 if (Exp2)
948 BN_clear_free(Exp2);
949
950 return (ret);
951
952 }
953
954 static EVP_PKEY *
955 openssl_load_key(KMF_HANDLE_T handle, const char *file)
956 {
957 BIO *keyfile = NULL;
958 EVP_PKEY *pkey = NULL;
959 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
960 KMF_ENCODE_FORMAT format;
961 KMF_RETURN rv;
962 KMF_DATA filedata;
963
964 if (file == NULL) {
965 return (NULL);
966 }
967
968 if (kmf_get_file_format((char *)file, &format) != KMF_OK)
969 return (NULL);
970
971 keyfile = BIO_new_file(file, "rb");
972 if (keyfile == NULL) {
973 goto end;
974 }
975
976 if (format == KMF_FORMAT_ASN1) {
977 pkey = d2i_PrivateKey_bio(keyfile, NULL);
978 if (pkey == NULL) {
979
980 (void) BIO_free(keyfile);
981 keyfile = NULL;
982 /* Try odd ASN.1 variations */
983 rv = kmf_read_input_file(kmfh, (char *)file,
984 &filedata);
985 if (rv == KMF_OK) {
986 (void) readAltFormatPrivateKey(&filedata,
987 &pkey);
988 kmf_free_data(&filedata);
989 }
990 }
991 } else if (format == KMF_FORMAT_PEM ||
992 format == KMF_FORMAT_PEM_KEYPAIR) {
993 pkey = PEM_read_bio_PrivateKey(keyfile, NULL, NULL, NULL);
994 if (pkey == NULL) {
995 KMF_DATA derdata;
996 /*
997 * Check if this is the alt. format
998 * RSA private key file.
999 */
1000 rv = kmf_read_input_file(kmfh, (char *)file,
1001 &filedata);
1002 if (rv == KMF_OK) {
1003 uchar_t *d = NULL;
1004 int len;
1005 rv = kmf_pem_to_der(filedata.Data,
1006 filedata.Length, &d, &len);
1007 if (rv == KMF_OK && d != NULL) {
1008 derdata.Data = d;
1009 derdata.Length = (size_t)len;
1010 (void) readAltFormatPrivateKey(
1011 &derdata, &pkey);
1012 free(d);
1013 }
1014 kmf_free_data(&filedata);
1015 }
1016 }
1017 }
1018
1019 end:
1020 if (pkey == NULL)
1021 SET_ERROR(kmfh, ERR_get_error());
1022
1023 if (keyfile != NULL)
1024 (void) BIO_free(keyfile);
1025
1026 return (pkey);
1027 }
1028
1029 KMF_RETURN
1030 OpenSSL_FindCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
1031 {
1032 KMF_RETURN rv = KMF_OK;
1033 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1034 int i, n;
1035 uint32_t maxcerts = 0;
1036 uint32_t *num_certs;
1037 KMF_X509_DER_CERT *kmf_cert = NULL;
1038 char *dirpath = NULL;
1039 char *filename = NULL;
1040 char *fullpath = NULL;
1041 char *issuer = NULL;
1042 char *subject = NULL;
1043 KMF_BIGINT *serial = NULL;
1044 KMF_CERT_VALIDITY validity;
1045
1046 num_certs = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr);
1047 if (num_certs == NULL)
1048 return (KMF_ERR_BAD_PARAMETER);
1049
1050 /* num_certs should reference the size of kmf_cert */
1051 maxcerts = *num_certs;
1052 if (maxcerts == 0)
1053 maxcerts = 0xFFFFFFFF;
1054 *num_certs = 0;
1055
1056 /* Get the optional returned certificate list */
1057 kmf_cert = kmf_get_attr_ptr(KMF_X509_DER_CERT_ATTR, attrlist,
1058 numattr);
1059
1060 /*
1061 * The dirpath attribute and the filename attribute can not be NULL
1062 * at the same time.
1063 */
1064 dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
1065 filename = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist,
1066 numattr);
1067
1068 fullpath = get_fullpath(dirpath, filename);
1069 if (fullpath == NULL)
1070 return (KMF_ERR_BAD_PARAMETER);
1071
1072 /* Get optional search criteria attributes */
1073 issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr);
1074 subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr);
1075 serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr);
1076 rv = kmf_get_attr(KMF_CERT_VALIDITY_ATTR, attrlist, numattr,
1077 &validity, NULL);
1078 if (rv != KMF_OK) {
1079 validity = KMF_ALL_CERTS;
1080 rv = KMF_OK;
1081 }
1082
1083 if (isdir(fullpath)) {
1084 DIR *dirp;
1085 struct dirent *dp;
1086
1087 n = 0;
1088 /* open all files in the directory and attempt to read them */
1089 if ((dirp = opendir(fullpath)) == NULL) {
1090 return (KMF_ERR_BAD_PARAMETER);
1091 }
1092 while ((dp = readdir(dirp)) != NULL) {
1093 char *fname;
1094 KMF_DATA *certlist = NULL;
1095 uint32_t loaded_certs = 0;
1096
1097 if (strcmp(dp->d_name, ".") == 0 ||
1098 strcmp(dp->d_name, "..") == 0)
1099 continue;
1100
1101 fname = get_fullpath(fullpath, (char *)&dp->d_name);
1102
1103 rv = load_certs(kmfh, issuer, subject, serial,
1104 validity, fname, &certlist, &loaded_certs);
1105
1106 if (rv != KMF_OK) {
1107 free(fname);
1108 if (certlist != NULL) {
1109 for (i = 0; i < loaded_certs; i++)
1110 kmf_free_data(&certlist[i]);
1111 free(certlist);
1112 }
1113 continue;
1114 }
1115
1116 /* If load succeeds, add certdata to the list */
1117 if (kmf_cert != NULL) {
1118 for (i = 0; i < loaded_certs &&
1119 n < maxcerts; i++) {
1120 kmf_cert[n].certificate.Data =
1121 certlist[i].Data;
1122 kmf_cert[n].certificate.Length =
1123 certlist[i].Length;
1124
1125 kmf_cert[n].kmf_private.keystore_type =
1126 KMF_KEYSTORE_OPENSSL;
1127 kmf_cert[n].kmf_private.flags =
1128 KMF_FLAG_CERT_VALID;
1129 kmf_cert[n].kmf_private.label =
1130 strdup(fname);
1131 n++;
1132 }
1133 /*
1134 * If maxcerts < loaded_certs, clean up the
1135 * certs that were not used.
1136 */
1137 for (; i < loaded_certs; i++)
1138 kmf_free_data(&certlist[i]);
1139 } else {
1140 for (i = 0; i < loaded_certs; i++)
1141 kmf_free_data(&certlist[i]);
1142 n += loaded_certs;
1143 }
1144 free(certlist);
1145 free(fname);
1146 }
1147 (*num_certs) = n;
1148 if (*num_certs == 0)
1149 rv = KMF_ERR_CERT_NOT_FOUND;
1150 if (*num_certs > 0)
1151 rv = KMF_OK;
1152 exit:
1153 (void) closedir(dirp);
1154 } else {
1155 KMF_DATA *certlist = NULL;
1156 uint32_t loaded_certs = 0;
1157
1158 rv = load_certs(kmfh, issuer, subject, serial, validity,
1159 fullpath, &certlist, &loaded_certs);
1160 if (rv != KMF_OK) {
1161 free(fullpath);
1162 return (rv);
1163 }
1164
1165 n = 0;
1166 if (kmf_cert != NULL && certlist != NULL) {
1167 for (i = 0; i < loaded_certs && i < maxcerts; i++) {
1168 kmf_cert[n].certificate.Data =
1169 certlist[i].Data;
1170 kmf_cert[n].certificate.Length =
1171 certlist[i].Length;
1172 kmf_cert[n].kmf_private.keystore_type =
1173 KMF_KEYSTORE_OPENSSL;
1174 kmf_cert[n].kmf_private.flags =
1175 KMF_FLAG_CERT_VALID;
1176 kmf_cert[n].kmf_private.label =
1177 strdup(fullpath);
1178 n++;
1179 }
1180 /* If maxcerts < loaded_certs, clean up */
1181 for (; i < loaded_certs; i++)
1182 kmf_free_data(&certlist[i]);
1183 } else if (certlist != NULL) {
1184 for (i = 0; i < loaded_certs; i++)
1185 kmf_free_data(&certlist[i]);
1186 n = loaded_certs;
1187 }
1188 if (certlist != NULL)
1189 free(certlist);
1190 *num_certs = n;
1191 }
1192
1193 free(fullpath);
1194
1195 return (rv);
1196 }
1197
1198 void
1199 /*ARGSUSED*/
1200 OpenSSL_FreeKMFCert(KMF_HANDLE_T handle,
1201 KMF_X509_DER_CERT *kmf_cert)
1202 {
1203 if (kmf_cert != NULL) {
1204 if (kmf_cert->certificate.Data != NULL) {
1205 kmf_free_data(&kmf_cert->certificate);
1206 }
1207 if (kmf_cert->kmf_private.label)
1208 free(kmf_cert->kmf_private.label);
1209 }
1210 }
1211
1212 /*ARGSUSED*/
1213 KMF_RETURN
1214 OpenSSL_StoreCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
1215 {
1216 KMF_RETURN ret = KMF_OK;
1217 KMF_DATA *cert = NULL;
1218 char *outfilename = NULL;
1219 char *dirpath = NULL;
1220 char *fullpath = NULL;
1221 KMF_ENCODE_FORMAT format;
1222
1223 /* Get the cert data */
1224 cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr);
1225 if (cert == NULL || cert->Data == NULL)
1226 return (KMF_ERR_BAD_PARAMETER);
1227
1228 /* Check the output filename and directory attributes. */
1229 outfilename = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist,
1230 numattr);
1231 if (outfilename == NULL)
1232 return (KMF_ERR_BAD_PARAMETER);
1233
1234 dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
1235 fullpath = get_fullpath(dirpath, outfilename);
1236 if (fullpath == NULL)
1237 return (KMF_ERR_BAD_CERTFILE);
1238
1239 /* Check the optional format attribute */
1240 ret = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr,
1241 &format, NULL);
1242 if (ret != KMF_OK) {
1243 /* If there is no format attribute, then default to PEM */
1244 format = KMF_FORMAT_PEM;
1245 ret = KMF_OK;
1246 } else if (format != KMF_FORMAT_ASN1 && format != KMF_FORMAT_PEM) {
1247 ret = KMF_ERR_BAD_CERT_FORMAT;
1248 goto out;
1249 }
1250
1251 /* Store the certificate in the file with the specified format */
1252 ret = kmf_create_cert_file(cert, format, fullpath);
1253
1254 out:
1255 if (fullpath != NULL)
1256 free(fullpath);
1257
1258 return (ret);
1259 }
1260
1261
1262 KMF_RETURN
1263 OpenSSL_DeleteCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
1264 {
1265 KMF_RETURN rv;
1266 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1267 KMF_DATA certdata = {NULL, 0};
1268 char *dirpath = NULL;
1269 char *filename = NULL;
1270 char *fullpath = NULL;
1271 char *issuer = NULL;
1272 char *subject = NULL;
1273 KMF_BIGINT *serial = NULL;
1274 KMF_CERT_VALIDITY validity;
1275
1276 /*
1277 * Get the DIRPATH and CERT_FILENAME attributes. They can not be
1278 * NULL at the same time.
1279 */
1280 dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
1281 filename = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist,
1282 numattr);
1283 fullpath = get_fullpath(dirpath, filename);
1284 if (fullpath == NULL)
1285 return (KMF_ERR_BAD_PARAMETER);
1286
1287 /* Get optional search criteria attributes */
1288 issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr);
1289 subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr);
1290 serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr);
1291 rv = kmf_get_attr(KMF_CERT_VALIDITY_ATTR, attrlist, numattr,
1292 &validity, NULL);
1293 if (rv != KMF_OK) {
1294 validity = KMF_ALL_CERTS;
1295 rv = KMF_OK;
1296 }
1297
1298 if (isdir(fullpath)) {
1299 DIR *dirp;
1300 struct dirent *dp;
1301
1302 /* open all files in the directory and attempt to read them */
1303 if ((dirp = opendir(fullpath)) == NULL) {
1304 return (KMF_ERR_BAD_PARAMETER);
1305 }
1306
1307 while ((dp = readdir(dirp)) != NULL) {
1308 if (strcmp(dp->d_name, ".") != 0 &&
1309 strcmp(dp->d_name, "..") != 0) {
1310 char *fname;
1311
1312 fname = get_fullpath(fullpath,
1313 (char *)&dp->d_name);
1314
1315 if (fname == NULL) {
1316 rv = KMF_ERR_MEMORY;
1317 break;
1318 }
1319
1320 rv = kmf_load_cert(kmfh, issuer, subject,
1321 serial, validity, fname, &certdata);
1322
1323 if (rv == KMF_ERR_CERT_NOT_FOUND) {
1324 free(fname);
1325 kmf_free_data(&certdata);
1326 rv = KMF_OK;
1327 continue;
1328 } else if (rv != KMF_OK) {
1329 free(fname);
1330 break;
1331 }
1332
1333 if (unlink(fname) != 0) {
1334 SET_SYS_ERROR(kmfh, errno);
1335 rv = KMF_ERR_INTERNAL;
1336 free(fname);
1337 break;
1338 }
1339 free(fname);
1340 kmf_free_data(&certdata);
1341 }
1342 }
1343 (void) closedir(dirp);
1344 } else {
1345 /* Just try to load a single certificate */
1346 rv = kmf_load_cert(kmfh, issuer, subject, serial, validity,
1347 fullpath, &certdata);
1348 if (rv == KMF_OK) {
1349 if (unlink(fullpath) != 0) {
1350 SET_SYS_ERROR(kmfh, errno);
1351 rv = KMF_ERR_INTERNAL;
1352 }
1353 }
1354 }
1355
1356 out:
1357 if (fullpath != NULL)
1358 free(fullpath);
1359
1360 kmf_free_data(&certdata);
1361
1362 return (rv);
1363 }
1364
1365 KMF_RETURN
1366 OpenSSL_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key,
1367 KMF_DATA *keydata)
1368 {
1369 KMF_RETURN rv = KMF_OK;
1370 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1371 int n;
1372
1373 if (key == NULL || keydata == NULL ||
1374 key->keyp == NULL)
1375 return (KMF_ERR_BAD_PARAMETER);
1376
1377 if (key->keyalg == KMF_RSA) {
1378 RSA *pubkey = EVP_PKEY_get1_RSA(key->keyp);
1379
1380 if (!(n = i2d_RSA_PUBKEY(pubkey, &keydata->Data))) {
1381 SET_ERROR(kmfh, ERR_get_error());
1382 return (KMF_ERR_ENCODING);
1383 }
1384 RSA_free(pubkey);
1385 } else if (key->keyalg == KMF_DSA) {
1386 DSA *pubkey = EVP_PKEY_get1_DSA(key->keyp);
1387
1388 if (!(n = i2d_DSA_PUBKEY(pubkey, &keydata->Data))) {
1389 SET_ERROR(kmfh, ERR_get_error());
1390 return (KMF_ERR_ENCODING);
1391 }
1392 DSA_free(pubkey);
1393 } else {
1394 return (KMF_ERR_BAD_PARAMETER);
1395 }
1396 keydata->Length = n;
1397
1398 cleanup:
1399 if (rv != KMF_OK) {
1400 if (keydata->Data)
1401 free(keydata->Data);
1402 keydata->Data = NULL;
1403 keydata->Length = 0;
1404 }
1405
1406 return (rv);
1407 }
1408
1409 static KMF_RETURN
1410 ssl_write_key(KMF_HANDLE *kmfh, KMF_ENCODE_FORMAT format, BIO *out,
1411 KMF_CREDENTIAL *cred, EVP_PKEY *pkey, boolean_t private)
1412 {
1413 int rv = 0;
1414 RSA *rsa;
1415 DSA *dsa;
1416
1417 if (pkey == NULL || out == NULL)
1418 return (KMF_ERR_BAD_PARAMETER);
1419
1420 switch (format) {
1421 case KMF_FORMAT_RAWKEY:
1422 /* same as ASN.1 */
1423 case KMF_FORMAT_ASN1:
1424 if (pkey->type == EVP_PKEY_RSA) {
1425 rsa = EVP_PKEY_get1_RSA(pkey);
1426 if (private)
1427 rv = i2d_RSAPrivateKey_bio(out, rsa);
1428 else
1429 rv = i2d_RSAPublicKey_bio(out, rsa);
1430 RSA_free(rsa);
1431 } else if (pkey->type == EVP_PKEY_DSA) {
1432 dsa = EVP_PKEY_get1_DSA(pkey);
1433 rv = i2d_DSAPrivateKey_bio(out, dsa);
1434 DSA_free(dsa);
1435 }
1436 if (rv == 1) {
1437 rv = KMF_OK;
1438 } else {
1439 SET_ERROR(kmfh, rv);
1440 }
1441 break;
1442 case KMF_FORMAT_PEM:
1443 if (pkey->type == EVP_PKEY_RSA) {
1444 rsa = EVP_PKEY_get1_RSA(pkey);
1445 if (private)
1446 rv = PEM_write_bio_RSAPrivateKey(out,
1447 rsa, NULL, NULL, 0, NULL,
1448 (cred != NULL ? cred->cred : NULL));
1449 else
1450 rv = PEM_write_bio_RSAPublicKey(out,
1451 rsa);
1452 RSA_free(rsa);
1453 } else if (pkey->type == EVP_PKEY_DSA) {
1454 dsa = EVP_PKEY_get1_DSA(pkey);
1455 rv = PEM_write_bio_DSAPrivateKey(out,
1456 dsa, NULL, NULL, 0, NULL,
1457 (cred != NULL ? cred->cred : NULL));
1458 DSA_free(dsa);
1459 }
1460
1461 if (rv == 1) {
1462 rv = KMF_OK;
1463 } else {
1464 SET_ERROR(kmfh, rv);
1465 }
1466 break;
1467
1468 default:
1469 rv = KMF_ERR_BAD_PARAMETER;
1470 }
1471
1472 return (rv);
1473 }
1474
1475 KMF_RETURN
1476 OpenSSL_CreateKeypair(KMF_HANDLE_T handle, int numattr,
1477 KMF_ATTRIBUTE *attrlist)
1478 {
1479 KMF_RETURN rv = KMF_OK;
1480 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1481 uint32_t eValue = 0x010001;
1482 RSA *sslPrivKey = NULL;
1483 DSA *sslDSAKey = NULL;
1484 EVP_PKEY *eprikey = NULL;
1485 EVP_PKEY *epubkey = NULL;
1486 BIO *out = NULL;
1487 KMF_KEY_HANDLE *pubkey = NULL, *privkey = NULL;
1488 uint32_t keylen = 1024;
1489 uint32_t keylen_size = sizeof (uint32_t);
1490 boolean_t storekey = TRUE;
1491 KMF_KEY_ALG keytype = KMF_RSA;
1492
1493 rv = kmf_get_attr(KMF_STOREKEY_BOOL_ATTR, attrlist, numattr,
1494 &storekey, NULL);
1495 if (rv != KMF_OK) {
1496 /* "storekey" is optional. Default is TRUE */
1497 rv = KMF_OK;
1498 }
1499
1500 rv = kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr,
1501 (void *)&keytype, NULL);
1502 if (rv != KMF_OK)
1503 /* keytype is optional. KMF_RSA is default */
1504 rv = KMF_OK;
1505
1506 pubkey = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attrlist, numattr);
1507 if (pubkey == NULL)
1508 return (KMF_ERR_BAD_PARAMETER);
1509
1510 privkey = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attrlist, numattr);
1511 if (privkey == NULL)
1512 return (KMF_ERR_BAD_PARAMETER);
1513
1514 (void) memset(pubkey, 0, sizeof (KMF_KEY_HANDLE));
1515 (void) memset(privkey, 0, sizeof (KMF_KEY_HANDLE));
1516
1517 eprikey = EVP_PKEY_new();
1518 if (eprikey == NULL) {
1519 SET_ERROR(kmfh, ERR_get_error());
1520 rv = KMF_ERR_KEYGEN_FAILED;
1521 goto cleanup;
1522 }
1523 epubkey = EVP_PKEY_new();
1524 if (epubkey == NULL) {
1525 SET_ERROR(kmfh, ERR_get_error());
1526 rv = KMF_ERR_KEYGEN_FAILED;
1527 goto cleanup;
1528 }
1529 if (keytype == KMF_RSA) {
1530 KMF_BIGINT *rsaexp = NULL;
1531
1532 rsaexp = kmf_get_attr_ptr(KMF_RSAEXP_ATTR, attrlist, numattr);
1533 if (rsaexp != NULL) {
1534 if (rsaexp->len > 0 &&
1535 rsaexp->len <= sizeof (eValue) &&
1536 rsaexp->val != NULL) {
1537 /* LINTED E_BAD_PTR_CAST_ALIGN */
1538 eValue = *(uint32_t *)rsaexp->val;
1539 } else {
1540 rv = KMF_ERR_BAD_PARAMETER;
1541 goto cleanup;
1542 }
1543 } else {
1544 /* RSA Exponent is optional. Default is 0x10001 */
1545 rv = KMF_OK;
1546 }
1547
1548 rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr,
1549 &keylen, &keylen_size);
1550 if (rv == KMF_ERR_ATTR_NOT_FOUND)
1551 /* keylen is optional, default is 1024 */
1552 rv = KMF_OK;
1553 if (rv != KMF_OK) {
1554 rv = KMF_ERR_BAD_PARAMETER;
1555 goto cleanup;
1556 }
1557
1558 sslPrivKey = RSA_generate_key(keylen, eValue, NULL, NULL);
1559 if (sslPrivKey == NULL) {
1560 SET_ERROR(kmfh, ERR_get_error());
1561 rv = KMF_ERR_KEYGEN_FAILED;
1562 } else {
1563 (void) EVP_PKEY_set1_RSA(eprikey, sslPrivKey);
1564 privkey->kstype = KMF_KEYSTORE_OPENSSL;
1565 privkey->keyalg = KMF_RSA;
1566 privkey->keyclass = KMF_ASYM_PRI;
1567 privkey->israw = FALSE;
1568 privkey->keyp = (void *)eprikey;
1569
1570 /* OpenSSL derives the public key from the private */
1571 (void) EVP_PKEY_set1_RSA(epubkey, sslPrivKey);
1572 pubkey->kstype = KMF_KEYSTORE_OPENSSL;
1573 pubkey->keyalg = KMF_RSA;
1574 pubkey->israw = FALSE;
1575 pubkey->keyclass = KMF_ASYM_PUB;
1576 pubkey->keyp = (void *)epubkey;
1577 }
1578 } else if (keytype == KMF_DSA) {
1579 DSA *dp;
1580 sslDSAKey = DSA_new();
1581 if (sslDSAKey == NULL) {
1582 SET_ERROR(kmfh, ERR_get_error());
1583 return (KMF_ERR_MEMORY);
1584 }
1585
1586 if ((sslDSAKey->p = BN_bin2bn(P, sizeof (P), sslDSAKey->p)) ==
1587 NULL) {
1588 SET_ERROR(kmfh, ERR_get_error());
1589 rv = KMF_ERR_KEYGEN_FAILED;
1590 goto cleanup;
1591 }
1592 if ((sslDSAKey->q = BN_bin2bn(Q, sizeof (Q), sslDSAKey->q)) ==
1593 NULL) {
1594 SET_ERROR(kmfh, ERR_get_error());
1595 rv = KMF_ERR_KEYGEN_FAILED;
1596 goto cleanup;
1597 }
1598 if ((sslDSAKey->g = BN_bin2bn(G, sizeof (G), sslDSAKey->g)) ==
1599 NULL) {
1600 SET_ERROR(kmfh, ERR_get_error());
1601 rv = KMF_ERR_KEYGEN_FAILED;
1602 goto cleanup;
1603 }
1604
1605 if (!DSA_generate_key(sslDSAKey)) {
1606 SET_ERROR(kmfh, ERR_get_error());
1607 rv = KMF_ERR_KEYGEN_FAILED;
1608 goto cleanup;
1609 }
1610
1611 privkey->kstype = KMF_KEYSTORE_OPENSSL;
1612 privkey->keyalg = KMF_DSA;
1613 privkey->keyclass = KMF_ASYM_PRI;
1614 privkey->israw = FALSE;
1615 if (EVP_PKEY_set1_DSA(eprikey, sslDSAKey)) {
1616 privkey->keyp = (void *)eprikey;
1617 } else {
1618 SET_ERROR(kmfh, ERR_get_error());
1619 rv = KMF_ERR_KEYGEN_FAILED;
1620 goto cleanup;
1621 }
1622 dp = DSA_new();
1623 /* Make a copy for the public key */
1624 if (dp != NULL) {
1625 if ((dp->p = BN_new()) == NULL) {
1626 SET_ERROR(kmfh, ERR_get_error());
1627 rv = KMF_ERR_MEMORY;
1628 DSA_free(dp);
1629 goto cleanup;
1630 }
1631 if ((dp->q = BN_new()) == NULL) {
1632 SET_ERROR(kmfh, ERR_get_error());
1633 rv = KMF_ERR_MEMORY;
1634 BN_free(dp->p);
1635 DSA_free(dp);
1636 goto cleanup;
1637 }
1638 if ((dp->g = BN_new()) == NULL) {
1639 SET_ERROR(kmfh, ERR_get_error());
1640 rv = KMF_ERR_MEMORY;
1641 BN_free(dp->q);
1642 BN_free(dp->p);
1643 DSA_free(dp);
1644 goto cleanup;
1645 }
1646 if ((dp->pub_key = BN_new()) == NULL) {
1647 SET_ERROR(kmfh, ERR_get_error());
1648 rv = KMF_ERR_MEMORY;
1649 BN_free(dp->q);
1650 BN_free(dp->p);
1651 BN_free(dp->g);
1652 DSA_free(dp);
1653 goto cleanup;
1654 }
1655 (void) BN_copy(dp->p, sslDSAKey->p);
1656 (void) BN_copy(dp->q, sslDSAKey->q);
1657 (void) BN_copy(dp->g, sslDSAKey->g);
1658 (void) BN_copy(dp->pub_key, sslDSAKey->pub_key);
1659
1660 pubkey->kstype = KMF_KEYSTORE_OPENSSL;
1661 pubkey->keyalg = KMF_DSA;
1662 pubkey->keyclass = KMF_ASYM_PUB;
1663 pubkey->israw = FALSE;
1664
1665 if (EVP_PKEY_set1_DSA(epubkey, sslDSAKey)) {
1666 pubkey->keyp = (void *)epubkey;
1667 } else {
1668 SET_ERROR(kmfh, ERR_get_error());
1669 rv = KMF_ERR_KEYGEN_FAILED;
1670 goto cleanup;
1671 }
1672 }
1673 }
1674
1675 if (rv != KMF_OK) {
1676 goto cleanup;
1677 }
1678
1679 if (storekey) {
1680 KMF_ATTRIBUTE storeattrs[4]; /* max. 4 attributes needed */
1681 int i = 0;
1682 char *keyfile = NULL, *dirpath = NULL;
1683 KMF_ENCODE_FORMAT format;
1684 /*
1685 * Construct a new attribute arrray and call openssl_store_key
1686 */
1687 kmf_set_attr_at_index(storeattrs, i, KMF_PRIVKEY_HANDLE_ATTR,
1688 privkey, sizeof (privkey));
1689 i++;
1690
1691 dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
1692 if (dirpath != NULL) {
1693 storeattrs[i].type = KMF_DIRPATH_ATTR;
1694 storeattrs[i].pValue = dirpath;
1695 storeattrs[i].valueLen = strlen(dirpath);
1696 i++;
1697 } else {
1698 rv = KMF_OK; /* DIRPATH is optional */
1699 }
1700 keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR,
1701 attrlist, numattr);
1702 if (keyfile != NULL) {
1703 storeattrs[i].type = KMF_KEY_FILENAME_ATTR;
1704 storeattrs[i].pValue = keyfile;
1705 storeattrs[i].valueLen = strlen(keyfile);
1706 i++;
1707 } else {
1708 goto cleanup; /* KEYFILE is required */
1709 }
1710 rv = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr,
1711 (void *)&format, NULL);
1712 if (rv == KMF_OK) {
1713 storeattrs[i].type = KMF_ENCODE_FORMAT_ATTR;
1714 storeattrs[i].pValue = &format;
1715 storeattrs[i].valueLen = sizeof (format);
1716 i++;
1717 }
1718
1719 rv = OpenSSL_StoreKey(handle, i, storeattrs);
1720 }
1721
1722 cleanup:
1723 if (rv != KMF_OK) {
1724 if (eprikey != NULL)
1725 EVP_PKEY_free(eprikey);
1726
1727 if (epubkey != NULL)
1728 EVP_PKEY_free(epubkey);
1729
1730 if (pubkey->keylabel) {
1731 free(pubkey->keylabel);
1732 pubkey->keylabel = NULL;
1733 }
1734
1735 if (privkey->keylabel) {
1736 free(privkey->keylabel);
1737 privkey->keylabel = NULL;
1738 }
1739
1740 pubkey->keyp = NULL;
1741 privkey->keyp = NULL;
1742 }
1743
1744 if (sslPrivKey)
1745 RSA_free(sslPrivKey);
1746
1747 if (sslDSAKey)
1748 DSA_free(sslDSAKey);
1749
1750 if (out != NULL)
1751 (void) BIO_free(out);
1752
1753 return (rv);
1754 }
1755
1756 /*
1757 * Make sure the BN conversion is properly padded with 0x00
1758 * bytes. If not, signature verification for DSA signatures
1759 * may fail in the case where the bignum value does not use
1760 * all of the bits.
1761 */
1762 static int
1763 fixbnlen(BIGNUM *bn, unsigned char *buf, int len) {
1764 int bytes = len - BN_num_bytes(bn);
1765
1766 /* prepend with leading 0x00 if necessary */
1767 while (bytes-- > 0)
1768 *buf++ = 0;
1769
1770 (void) BN_bn2bin(bn, buf);
1771 /*
1772 * Return the desired length since we prepended it
1773 * with the necessary 0x00 padding.
1774 */
1775 return (len);
1776 }
1777
1778 KMF_RETURN
1779 OpenSSL_SignData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key,
1780 KMF_OID *AlgOID, KMF_DATA *tobesigned, KMF_DATA *output)
1781 {
1782 KMF_RETURN ret = KMF_OK;
1783 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1784 KMF_ALGORITHM_INDEX AlgId;
1785 EVP_MD_CTX ctx;
1786 const EVP_MD *md;
1787
1788 if (key == NULL || AlgOID == NULL ||
1789 tobesigned == NULL || output == NULL ||
1790 tobesigned->Data == NULL ||
1791 output->Data == NULL)
1792 return (KMF_ERR_BAD_PARAMETER);
1793
1794 /* Map the OID to an OpenSSL algorithm */
1795 AlgId = x509_algoid_to_algid(AlgOID);
1796 if (AlgId == KMF_ALGID_NONE)
1797 return (KMF_ERR_BAD_ALGORITHM);
1798
1799 if (key->keyalg == KMF_RSA) {
1800 EVP_PKEY *pkey = (EVP_PKEY *)key->keyp;
1801 uchar_t *p;
1802 int len;
1803 if (AlgId == KMF_ALGID_MD5WithRSA)
1804 md = EVP_md5();
1805 else if (AlgId == KMF_ALGID_MD2WithRSA)
1806 md = EVP_md2();
1807 else if (AlgId == KMF_ALGID_SHA1WithRSA)
1808 md = EVP_sha1();
1809 else if (AlgId == KMF_ALGID_SHA256WithRSA)
1810 md = EVP_sha256();
1811 else if (AlgId == KMF_ALGID_SHA384WithRSA)
1812 md = EVP_sha384();
1813 else if (AlgId == KMF_ALGID_SHA512WithRSA)
1814 md = EVP_sha512();
1815 else if (AlgId == KMF_ALGID_RSA)
1816 md = NULL;
1817 else
1818 return (KMF_ERR_BAD_ALGORITHM);
1819
1820 if ((md == NULL) && (AlgId == KMF_ALGID_RSA)) {
1821 RSA *rsa = EVP_PKEY_get1_RSA((EVP_PKEY *)pkey);
1822
1823 p = output->Data;
1824 if ((len = RSA_private_encrypt(tobesigned->Length,
1825 tobesigned->Data, p, rsa,
1826 RSA_PKCS1_PADDING)) <= 0) {
1827 SET_ERROR(kmfh, ERR_get_error());
1828 ret = KMF_ERR_INTERNAL;
1829 }
1830 output->Length = len;
1831 } else {
1832 (void) EVP_MD_CTX_init(&ctx);
1833 (void) EVP_SignInit_ex(&ctx, md, NULL);
1834 (void) EVP_SignUpdate(&ctx, tobesigned->Data,
1835 (uint32_t)tobesigned->Length);
1836 len = (uint32_t)output->Length;
1837 p = output->Data;
1838 if (!EVP_SignFinal(&ctx, p, (uint32_t *)&len, pkey)) {
1839 SET_ERROR(kmfh, ERR_get_error());
1840 len = 0;
1841 ret = KMF_ERR_INTERNAL;
1842 }
1843 output->Length = len;
1844 (void) EVP_MD_CTX_cleanup(&ctx);
1845 }
1846 } else if (key->keyalg == KMF_DSA) {
1847 DSA *dsa = EVP_PKEY_get1_DSA(key->keyp);
1848
1849 uchar_t hash[EVP_MAX_MD_SIZE];
1850 uint32_t hashlen;
1851 DSA_SIG *dsasig;
1852
1853 if (AlgId == KMF_ALGID_DSA ||
1854 AlgId == KMF_ALGID_SHA1WithDSA)
1855 md = EVP_sha1();
1856 else if (AlgId == KMF_ALGID_SHA256WithDSA)
1857 md = EVP_sha256();
1858 else /* Bad algorithm */
1859 return (KMF_ERR_BAD_ALGORITHM);
1860
1861 /*
1862 * OpenSSL EVP_Sign operation automatically converts to
1863 * ASN.1 output so we do the operations separately so we
1864 * are assured of NOT getting ASN.1 output returned.
1865 * KMF does not want ASN.1 encoded results because
1866 * not all mechanisms return ASN.1 encodings (PKCS#11
1867 * and NSS return raw signature data).
1868 */
1869 EVP_MD_CTX_init(&ctx);
1870 (void) EVP_DigestInit_ex(&ctx, md, NULL);
1871 (void) EVP_DigestUpdate(&ctx, tobesigned->Data,
1872 tobesigned->Length);
1873 (void) EVP_DigestFinal_ex(&ctx, hash, &hashlen);
1874
1875 /* Only sign first 20 bytes for SHA2 */
1876 if (AlgId == KMF_ALGID_SHA256WithDSA)
1877 hashlen = 20;
1878 dsasig = DSA_do_sign(hash, hashlen, dsa);
1879 if (dsasig != NULL) {
1880 int i;
1881 output->Length = i = fixbnlen(dsasig->r, output->Data,
1882 hashlen);
1883
1884 output->Length += fixbnlen(dsasig->s, &output->Data[i],
1885 hashlen);
1886
1887 DSA_SIG_free(dsasig);
1888 } else {
1889 SET_ERROR(kmfh, ERR_get_error());
1890 }
1891 (void) EVP_MD_CTX_cleanup(&ctx);
1892 } else {
1893 return (KMF_ERR_BAD_PARAMETER);
1894 }
1895 cleanup:
1896 return (ret);
1897 }
1898
1899 KMF_RETURN
1900 /*ARGSUSED*/
1901 OpenSSL_DeleteKey(KMF_HANDLE_T handle,
1902 int numattr, KMF_ATTRIBUTE *attrlist)
1903 {
1904 KMF_RETURN rv = KMF_OK;
1905 KMF_KEY_HANDLE *key;
1906 boolean_t destroy = B_TRUE;
1907
1908 key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
1909 if (key == NULL || key->keyp == NULL)
1910 return (KMF_ERR_BAD_PARAMETER);
1911
1912 rv = kmf_get_attr(KMF_DESTROY_BOOL_ATTR, attrlist, numattr,
1913 (void *)&destroy, NULL);
1914 if (rv != KMF_OK) {
1915 /* "destroy" is optional. Default is TRUE */
1916 rv = KMF_OK;
1917 }
1918
1919 if (key->keyclass != KMF_ASYM_PUB &&
1920 key->keyclass != KMF_ASYM_PRI &&
1921 key->keyclass != KMF_SYMMETRIC)
1922 return (KMF_ERR_BAD_KEY_CLASS);
1923
1924 if (key->keyclass == KMF_SYMMETRIC) {
1925 kmf_free_raw_sym_key((KMF_RAW_SYM_KEY *)key->keyp);
1926 key->keyp = NULL;
1927 } else {
1928 if (key->keyp != NULL) {
1929 EVP_PKEY_free(key->keyp);
1930 key->keyp = NULL;
1931 }
1932 }
1933
1934 if (key->keylabel != NULL) {
1935 EVP_PKEY *pkey = NULL;
1936 /* If the file exists, make sure it is a proper key. */
1937 pkey = openssl_load_key(handle, key->keylabel);
1938 if (pkey == NULL) {
1939 if (key->keylabel != NULL) {
1940 free(key->keylabel);
1941 key->keylabel = NULL;
1942 }
1943 return (KMF_ERR_KEY_NOT_FOUND);
1944 }
1945 EVP_PKEY_free(pkey);
1946
1947 if (destroy) {
1948 if (unlink(key->keylabel) != 0) {
1949 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1950 SET_SYS_ERROR(kmfh, errno);
1951 rv = KMF_ERR_INTERNAL;
1952 }
1953 }
1954 if (key->keylabel != NULL) {
1955 free(key->keylabel);
1956 key->keylabel = NULL;
1957 }
1958 }
1959 return (rv);
1960 }
1961
1962 KMF_RETURN
1963 OpenSSL_GetErrorString(KMF_HANDLE_T handle, char **msgstr)
1964 {
1965 KMF_RETURN ret = KMF_OK;
1966 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1967 char str[256]; /* OpenSSL needs at least 120 byte buffer */
1968
1969 ERR_error_string_n(kmfh->lasterr.errcode, str, sizeof (str));
1970 if (strlen(str)) {
1971 *msgstr = (char *)strdup(str);
1972 if ((*msgstr) == NULL)
1973 ret = KMF_ERR_MEMORY;
1974 } else {
1975 *msgstr = NULL;
1976 }
1977
1978 return (ret);
1979 }
1980
1981 static int
1982 ext2NID(int kmfext)
1983 {
1984 switch (kmfext) {
1985 case KMF_X509_EXT_KEY_USAGE:
1986 return (NID_key_usage);
1987 case KMF_X509_EXT_PRIV_KEY_USAGE_PERIOD:
1988 return (NID_private_key_usage_period);
1989 case KMF_X509_EXT_CERT_POLICIES:
1990 return (NID_certificate_policies);
1991 case KMF_X509_EXT_SUBJ_ALTNAME:
1992 return (NID_subject_alt_name);
1993 case KMF_X509_EXT_ISSUER_ALTNAME:
1994 return (NID_issuer_alt_name);
1995 case KMF_X509_EXT_BASIC_CONSTRAINTS:
1996 return (NID_basic_constraints);
1997 case KMF_X509_EXT_EXT_KEY_USAGE:
1998 return (NID_ext_key_usage);
1999 case KMF_X509_EXT_AUTH_KEY_ID:
2000 return (NID_authority_key_identifier);
2001 case KMF_X509_EXT_CRL_DIST_POINTS:
2002 return (NID_crl_distribution_points);
2003 case KMF_X509_EXT_SUBJ_KEY_ID:
2004 return (NID_subject_key_identifier);
2005 case KMF_X509_EXT_POLICY_MAPPINGS:
2006 return (OBJ_sn2nid("policyMappings"));
2007 case KMF_X509_EXT_NAME_CONSTRAINTS:
2008 return (OBJ_sn2nid("nameConstraints"));
2009 case KMF_X509_EXT_POLICY_CONSTRAINTS:
2010 return (OBJ_sn2nid("policyConstraints"));
2011 case KMF_X509_EXT_INHIBIT_ANY_POLICY:
2012 return (OBJ_sn2nid("inhibitAnyPolicy"));
2013 case KMF_X509_EXT_FRESHEST_CRL:
2014 return (OBJ_sn2nid("freshestCRL"));
2015 default:
2016 return (NID_undef);
2017 }
2018 }
2019
2020 KMF_RETURN
2021 OpenSSL_CertGetPrintable(KMF_HANDLE_T handle, const KMF_DATA *pcert,
2022 KMF_PRINTABLE_ITEM flag, char *resultStr)
2023 {
2024 KMF_RETURN ret = KMF_OK;
2025 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2026 X509 *xcert = NULL;
2027 unsigned char *outbuf = NULL;
2028 unsigned char *outbuf_p;
2029 char *tmpstr = NULL;
2030 int j;
2031 int ext_index, nid, len;
2032 BIO *mem = NULL;
2033 #if OPENSSL_VERSION_NUMBER < 0x10000000L
2034 STACK *emlst = NULL;
2035 #else
2036 STACK_OF(OPENSSL_STRING) *emlst = NULL;
2037 #endif
2038 X509_EXTENSION *ex;
2039 X509_CINF *ci;
2040
2041 if (pcert == NULL || pcert->Data == NULL || pcert->Length == 0) {
2042 return (KMF_ERR_BAD_PARAMETER);
2043 }
2044
2045 /* copy cert data to outbuf */
2046 outbuf = malloc(pcert->Length);
2047 if (outbuf == NULL) {
2048 return (KMF_ERR_MEMORY);
2049 }
2050 (void) memcpy(outbuf, pcert->Data, pcert->Length);
2051
2052 outbuf_p = outbuf; /* use a temp pointer; required by openssl */
2053 xcert = d2i_X509(NULL, (const uchar_t **)&outbuf_p, pcert->Length);
2054 if (xcert == NULL) {
2055 SET_ERROR(kmfh, ERR_get_error());
2056 ret = KMF_ERR_ENCODING;
2057 goto out;
2058 }
2059
2060 mem = BIO_new(BIO_s_mem());
2061 if (mem == NULL) {
2062 SET_ERROR(kmfh, ERR_get_error());
2063 ret = KMF_ERR_MEMORY;
2064 goto out;
2065 }
2066
2067 switch (flag) {
2068 case KMF_CERT_ISSUER:
2069 (void) X509_NAME_print_ex(mem, X509_get_issuer_name(xcert), 0,
2070 XN_FLAG_SEP_CPLUS_SPC);
2071 len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2072 break;
2073
2074 case KMF_CERT_SUBJECT:
2075 (void) X509_NAME_print_ex(mem, X509_get_subject_name(xcert), 0,
2076 XN_FLAG_SEP_CPLUS_SPC);
2077 len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2078 break;
2079
2080 case KMF_CERT_VERSION:
2081 tmpstr = i2s_ASN1_INTEGER(NULL, xcert->cert_info->version);
2082 (void) strncpy(resultStr, tmpstr, KMF_CERT_PRINTABLE_LEN);
2083 OPENSSL_free(tmpstr);
2084 len = strlen(resultStr);
2085 break;
2086
2087 case KMF_CERT_SERIALNUM:
2088 if (i2a_ASN1_INTEGER(mem, X509_get_serialNumber(xcert)) > 0) {
2089 (void) strcpy(resultStr, "0x");
2090 len = BIO_gets(mem, &resultStr[2],
2091 KMF_CERT_PRINTABLE_LEN - 2);
2092 }
2093 break;
2094
2095 case KMF_CERT_NOTBEFORE:
2096 (void) ASN1_TIME_print(mem, X509_get_notBefore(xcert));
2097 len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2098 break;
2099
2100 case KMF_CERT_NOTAFTER:
2101 (void) ASN1_TIME_print(mem, X509_get_notAfter(xcert));
2102 len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2103 break;
2104
2105 case KMF_CERT_PUBKEY_DATA:
2106 {
2107 EVP_PKEY *pkey = X509_get_pubkey(xcert);
2108 if (pkey == NULL) {
2109 SET_ERROR(kmfh, ERR_get_error());
2110 ret = KMF_ERR_ENCODING;
2111 goto out;
2112 }
2113
2114 if (pkey->type == EVP_PKEY_RSA) {
2115 (void) BIO_printf(mem,
2116 "RSA Public Key: (%d bit)\n",
2117 BN_num_bits(pkey->pkey.rsa->n));
2118 (void) RSA_print(mem, pkey->pkey.rsa, 0);
2119 } else if (pkey->type == EVP_PKEY_DSA) {
2120 (void) BIO_printf(mem,
2121 "%12sDSA Public Key:\n", "");
2122 (void) DSA_print(mem, pkey->pkey.dsa, 0);
2123 } else {
2124 (void) BIO_printf(mem,
2125 "%12sUnknown Public Key:\n", "");
2126 }
2127 (void) BIO_printf(mem, "\n");
2128 EVP_PKEY_free(pkey);
2129 }
2130 len = BIO_read(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2131 break;
2132 case KMF_CERT_SIGNATURE_ALG:
2133 case KMF_CERT_PUBKEY_ALG:
2134 if (flag == KMF_CERT_SIGNATURE_ALG) {
2135 len = i2a_ASN1_OBJECT(mem,
2136 xcert->sig_alg->algorithm);
2137 } else {
2138 len = i2a_ASN1_OBJECT(mem,
2139 xcert->cert_info->key->algor->algorithm);
2140 }
2141
2142 if (len > 0) {
2143 len = BIO_read(mem, resultStr,
2144 KMF_CERT_PRINTABLE_LEN);
2145 }
2146 break;
2147
2148 case KMF_CERT_EMAIL:
2149 emlst = X509_get1_email(xcert);
2150 #if OPENSSL_VERSION_NUMBER < 0x10000000L
2151 for (j = 0; j < sk_num(emlst); j++)
2152 (void) BIO_printf(mem, "%s\n", sk_value(emlst, j));
2153 #else
2154 for (j = 0; j < sk_OPENSSL_STRING_num(emlst); j++)
2155 (void) BIO_printf(mem, "%s\n",
2156 sk_OPENSSL_STRING_value(emlst, j));
2157 #endif
2158
2159 len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2160 X509_email_free(emlst);
2161 break;
2162 case KMF_X509_EXT_ISSUER_ALTNAME:
2163 case KMF_X509_EXT_SUBJ_ALTNAME:
2164 case KMF_X509_EXT_KEY_USAGE:
2165 case KMF_X509_EXT_PRIV_KEY_USAGE_PERIOD:
2166 case KMF_X509_EXT_CERT_POLICIES:
2167 case KMF_X509_EXT_BASIC_CONSTRAINTS:
2168 case KMF_X509_EXT_NAME_CONSTRAINTS:
2169 case KMF_X509_EXT_POLICY_CONSTRAINTS:
2170 case KMF_X509_EXT_EXT_KEY_USAGE:
2171 case KMF_X509_EXT_INHIBIT_ANY_POLICY:
2172 case KMF_X509_EXT_AUTH_KEY_ID:
2173 case KMF_X509_EXT_SUBJ_KEY_ID:
2174 case KMF_X509_EXT_POLICY_MAPPINGS:
2175 case KMF_X509_EXT_CRL_DIST_POINTS:
2176 case KMF_X509_EXT_FRESHEST_CRL:
2177 nid = ext2NID(flag);
2178 if (nid == NID_undef) {
2179 ret = KMF_ERR_EXTENSION_NOT_FOUND;
2180 goto out;
2181 }
2182 ci = xcert->cert_info;
2183
2184 ext_index = X509v3_get_ext_by_NID(ci->extensions, nid, -1);
2185 if (ext_index == -1) {
2186 SET_ERROR(kmfh, ERR_get_error());
2187
2188 ret = KMF_ERR_EXTENSION_NOT_FOUND;
2189 goto out;
2190 }
2191 ex = X509v3_get_ext(ci->extensions, ext_index);
2192
2193 (void) i2a_ASN1_OBJECT(mem, X509_EXTENSION_get_object(ex));
2194
2195 if (BIO_printf(mem, ": %s\n",
2196 X509_EXTENSION_get_critical(ex) ? "critical" : "") <= 0) {
2197 SET_ERROR(kmfh, ERR_get_error());
2198 ret = KMF_ERR_ENCODING;
2199 goto out;
2200 }
2201 if (!X509V3_EXT_print(mem, ex, X509V3_EXT_DUMP_UNKNOWN, 4)) {
2202 (void) BIO_printf(mem, "%*s", 4, "");
2203 (void) M_ASN1_OCTET_STRING_print(mem, ex->value);
2204 }
2205 if (BIO_write(mem, "\n", 1) <= 0) {
2206 SET_ERROR(kmfh, ERR_get_error());
2207 ret = KMF_ERR_ENCODING;
2208 goto out;
2209 }
2210 len = BIO_read(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2211 }
2212 if (len <= 0) {
2213 SET_ERROR(kmfh, ERR_get_error());
2214 ret = KMF_ERR_ENCODING;
2215 }
2216
2217 out:
2218 if (outbuf != NULL) {
2219 free(outbuf);
2220 }
2221
2222 if (xcert != NULL) {
2223 X509_free(xcert);
2224 }
2225
2226 if (mem != NULL) {
2227 (void) BIO_free(mem);
2228 }
2229
2230 return (ret);
2231 }
2232
2233 KMF_RETURN
2234 /*ARGSUSED*/
2235 OpenSSL_FindPrikeyByCert(KMF_HANDLE_T handle, int numattr,
2236 KMF_ATTRIBUTE *attrlist)
2237 {
2238 KMF_RETURN rv = KMF_OK;
2239 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
2240 KMF_KEY_CLASS keyclass = KMF_ASYM_PRI;
2241 KMF_KEY_HANDLE *key = NULL;
2242 uint32_t numkeys = 1; /* 1 key only */
2243 char *dirpath = NULL;
2244 char *keyfile = NULL;
2245 KMF_ATTRIBUTE new_attrlist[16];
2246 int i = 0;
2247
2248 /*
2249 * This is really just a FindKey operation, reuse the
2250 * FindKey function.
2251 */
2252 kmf_set_attr_at_index(new_attrlist, i,
2253 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
2254 i++;
2255
2256 kmf_set_attr_at_index(new_attrlist, i,
2257 KMF_COUNT_ATTR, &numkeys, sizeof (uint32_t));
2258 i++;
2259
2260 kmf_set_attr_at_index(new_attrlist, i,
2261 KMF_KEYCLASS_ATTR, &keyclass, sizeof (keyclass));
2262 i++;
2263
2264 key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
2265 if (key == NULL) {
2266 return (KMF_ERR_BAD_PARAMETER);
2267 } else {
2268 kmf_set_attr_at_index(new_attrlist, i,
2269 KMF_KEY_HANDLE_ATTR, key, sizeof (KMF_KEY_HANDLE));
2270 i++;
2271 }
2272
2273 dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
2274 if (dirpath != NULL) {
2275 kmf_set_attr_at_index(new_attrlist, i,
2276 KMF_DIRPATH_ATTR, dirpath, strlen(dirpath));
2277 i++;
2278 }
2279
2280 keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr);
2281 if (keyfile == NULL)
2282 return (KMF_ERR_BAD_PARAMETER);
2283 else {
2284 kmf_set_attr_at_index(new_attrlist, i,
2285 KMF_KEY_FILENAME_ATTR, keyfile, strlen(keyfile));
2286 i++;
2287 }
2288
2289 rv = OpenSSL_FindKey(handle, i, new_attrlist);
2290 return (rv);
2291 }
2292
2293 KMF_RETURN
2294 /*ARGSUSED*/
2295 OpenSSL_DecryptData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key,
2296 KMF_OID *AlgOID, KMF_DATA *ciphertext,
2297 KMF_DATA *output)
2298 {
2299 KMF_RETURN ret = KMF_OK;
2300 RSA *rsa = NULL;
2301 unsigned int in_len = 0, out_len = 0;
2302 unsigned int total_decrypted = 0, modulus_len = 0;
2303 uint8_t *in_data, *out_data;
2304 int i, blocks;
2305
2306 if (key == NULL || AlgOID == NULL ||
2307 ciphertext == NULL || output == NULL ||
2308 ciphertext->Data == NULL ||
2309 output->Data == NULL)
2310 return (KMF_ERR_BAD_PARAMETER);
2311
2312 if (key->keyalg == KMF_RSA) {
2313 rsa = EVP_PKEY_get1_RSA((EVP_PKEY *)key->keyp);
2314 modulus_len = RSA_size(rsa);
2315 } else {
2316 return (KMF_ERR_BAD_PARAMETER);
2317 }
2318
2319 blocks = ciphertext->Length/modulus_len;
2320 out_data = output->Data;
2321 in_data = ciphertext->Data;
2322 out_len = modulus_len - 11;
2323 in_len = modulus_len;
2324
2325 for (i = 0; i < blocks; i++) {
2326 out_len = RSA_private_decrypt(in_len,
2327 in_data, out_data, rsa, RSA_PKCS1_PADDING);
2328
2329 if (out_len == 0) {
2330 ret = KMF_ERR_INTERNAL;
2331 goto cleanup;
2332 }
2333
2334 out_data += out_len;
2335 total_decrypted += out_len;
2336 in_data += in_len;
2337 }
2338
2339 output->Length = total_decrypted;
2340
2341 cleanup:
2342 RSA_free(rsa);
2343 if (ret != KMF_OK)
2344 output->Length = 0;
2345
2346 return (ret);
2347
2348 }
2349
2350 /*
2351 * This function will create a certid from issuer_cert and user_cert.
2352 * The caller should use OCSP_CERTID_free(OCSP_CERTID *) to deallocate
2353 * certid memory after use.
2354 */
2355 static KMF_RETURN
2356 create_certid(KMF_HANDLE_T handle, const KMF_DATA *issuer_cert,
2357 const KMF_DATA *user_cert, OCSP_CERTID **certid)
2358 {
2359 KMF_RETURN ret = KMF_OK;
2360 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2361 X509 *issuer = NULL;
2362 X509 *cert = NULL;
2363 unsigned char *ptmp;
2364
2365 if (issuer_cert == NULL || user_cert == NULL) {
2366 return (KMF_ERR_BAD_PARAMETER);
2367 }
2368
2369 /* convert the DER-encoded issuer cert to an internal X509 */
2370 ptmp = issuer_cert->Data;
2371 issuer = d2i_X509(NULL, (const uchar_t **)&ptmp,
2372 issuer_cert->Length);
2373 if (issuer == NULL) {
2374 SET_ERROR(kmfh, ERR_get_error());
2375 ret = KMF_ERR_OCSP_BAD_ISSUER;
2376 goto end;
2377 }
2378
2379 /* convert the DER-encoded user cert to an internal X509 */
2380 ptmp = user_cert->Data;
2381 cert = d2i_X509(NULL, (const uchar_t **)&ptmp,
2382 user_cert->Length);
2383 if (cert == NULL) {
2384 SET_ERROR(kmfh, ERR_get_error());
2385
2386 ret = KMF_ERR_OCSP_BAD_CERT;
2387 goto end;
2388 }
2389
2390 /* create a CERTID */
2391 *certid = OCSP_cert_to_id(NULL, cert, issuer);
2392 if (*certid == NULL) {
2393 SET_ERROR(kmfh, ERR_get_error());
2394 ret = KMF_ERR_OCSP_CERTID;
2395 goto end;
2396 }
2397
2398 end:
2399 if (issuer != NULL) {
2400 X509_free(issuer);
2401 }
2402
2403 if (cert != NULL) {
2404 X509_free(cert);
2405 }
2406
2407 return (ret);
2408 }
2409
2410 KMF_RETURN
2411 OpenSSL_CreateOCSPRequest(KMF_HANDLE_T handle,
2412 int numattr, KMF_ATTRIBUTE *attrlist)
2413 {
2414 KMF_RETURN ret = KMF_OK;
2415 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2416 OCSP_CERTID *id = NULL;
2417 OCSP_REQUEST *req = NULL;
2418 BIO *derbio = NULL;
2419 char *reqfile;
2420 KMF_DATA *issuer_cert;
2421 KMF_DATA *user_cert;
2422
2423 user_cert = kmf_get_attr_ptr(KMF_USER_CERT_DATA_ATTR,
2424 attrlist, numattr);
2425 if (user_cert == NULL)
2426 return (KMF_ERR_BAD_PARAMETER);
2427
2428 issuer_cert = kmf_get_attr_ptr(KMF_ISSUER_CERT_DATA_ATTR,
2429 attrlist, numattr);
2430 if (issuer_cert == NULL)
2431 return (KMF_ERR_BAD_PARAMETER);
2432
2433 reqfile = kmf_get_attr_ptr(KMF_OCSP_REQUEST_FILENAME_ATTR,
2434 attrlist, numattr);
2435 if (reqfile == NULL)
2436 return (KMF_ERR_BAD_PARAMETER);
2437
2438 ret = create_certid(handle, issuer_cert, user_cert, &id);
2439 if (ret != KMF_OK) {
2440 return (ret);
2441 }
2442
2443 /* Create an OCSP request */
2444 req = OCSP_REQUEST_new();
2445 if (req == NULL) {
2446 SET_ERROR(kmfh, ERR_get_error());
2447 ret = KMF_ERR_OCSP_CREATE_REQUEST;
2448 goto end;
2449 }
2450
2451 if (!OCSP_request_add0_id(req, id)) {
2452 ret = KMF_ERR_OCSP_CREATE_REQUEST;
2453 goto end;
2454 }
2455
2456 /* Write the request to the output file with DER encoding */
2457 derbio = BIO_new_file(reqfile, "wb");
2458 if (!derbio) {
2459 SET_ERROR(kmfh, ERR_get_error());
2460 ret = KMF_ERR_OPEN_FILE;
2461 goto end;
2462 }
2463 if (i2d_OCSP_REQUEST_bio(derbio, req) <= 0) {
2464 ret = KMF_ERR_ENCODING;
2465 }
2466
2467 end:
2468 /*
2469 * We don't need to free "id" explicitely, because OCSP_REQUEST_free()
2470 * will also deallocate certid's space.
2471 */
2472 if (req != NULL) {
2473 OCSP_REQUEST_free(req);
2474 }
2475
2476 if (derbio != NULL) {
2477 (void) BIO_free(derbio);
2478 }
2479
2480 return (ret);
2481 }
2482
2483 /* ocsp_find_signer_sk() is copied from openssl source */
2484 static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id)
2485 {
2486 int i;
2487 unsigned char tmphash[SHA_DIGEST_LENGTH], *keyhash;
2488
2489 /* Easy if lookup by name */
2490 if (id->type == V_OCSP_RESPID_NAME)
2491 return (X509_find_by_subject(certs, id->value.byName));
2492
2493 /* Lookup by key hash */
2494
2495 /* If key hash isn't SHA1 length then forget it */
2496 if (id->value.byKey->length != SHA_DIGEST_LENGTH)
2497 return (NULL);
2498
2499 keyhash = id->value.byKey->data;
2500 /* Calculate hash of each key and compare */
2501 for (i = 0; i < sk_X509_num(certs); i++) {
2502 X509 *x = sk_X509_value(certs, i);
2503 /* Use pubkey_digest to get the key ID value */
2504 (void) X509_pubkey_digest(x, EVP_sha1(), tmphash, NULL);
2505 if (!memcmp(keyhash, tmphash, SHA_DIGEST_LENGTH))
2506 return (x);
2507 }
2508 return (NULL);
2509 }
2510
2511 /* ocsp_find_signer() is copied from openssl source */
2512 /* ARGSUSED2 */
2513 static int
2514 ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, STACK_OF(X509) *certs,
2515 X509_STORE *st, unsigned long flags)
2516 {
2517 X509 *signer;
2518 OCSP_RESPID *rid = bs->tbsResponseData->responderId;
2519 if ((signer = ocsp_find_signer_sk(certs, rid))) {
2520 *psigner = signer;
2521 return (2);
2522 }
2523 if (!(flags & OCSP_NOINTERN) &&
2524 (signer = ocsp_find_signer_sk(bs->certs, rid))) {
2525 *psigner = signer;
2526 return (1);
2527 }
2528 /* Maybe lookup from store if by subject name */
2529
2530 *psigner = NULL;
2531 return (0);
2532 }
2533
2534 /*
2535 * This function will verify the signature of a basic response, using
2536 * the public key from the OCSP responder certificate.
2537 */
2538 static KMF_RETURN
2539 check_response_signature(KMF_HANDLE_T handle, OCSP_BASICRESP *bs,
2540 KMF_DATA *signer_cert, KMF_DATA *issuer_cert)
2541 {
2542 KMF_RETURN ret = KMF_OK;
2543 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2544 STACK_OF(X509) *cert_stack = NULL;
2545 X509 *signer = NULL;
2546 X509 *issuer = NULL;
2547 EVP_PKEY *skey = NULL;
2548 unsigned char *ptmp;
2549
2550
2551 if (bs == NULL || issuer_cert == NULL)
2552 return (KMF_ERR_BAD_PARAMETER);
2553
2554 /*
2555 * Find the certificate that signed the basic response.
2556 *
2557 * If signer_cert is not NULL, we will use that as the signer cert.
2558 * Otherwise, we will check if the issuer cert is actually the signer.
2559 * If we still do not find a signer, we will look for it from the
2560 * certificate list came with the response file.
2561 */
2562 if (signer_cert != NULL) {
2563 ptmp = signer_cert->Data;
2564 signer = d2i_X509(NULL, (const uchar_t **)&ptmp,
2565 signer_cert->Length);
2566 if (signer == NULL) {
2567 SET_ERROR(kmfh, ERR_get_error());
2568 ret = KMF_ERR_OCSP_BAD_SIGNER;
2569 goto end;
2570 }
2571 } else {
2572 /*
2573 * Convert the issuer cert into X509 and push it into a
2574 * stack to be used by ocsp_find_signer().
2575 */
2576 ptmp = issuer_cert->Data;
2577 issuer = d2i_X509(NULL, (const uchar_t **)&ptmp,
2578 issuer_cert->Length);
2579 if (issuer == NULL) {
2580 SET_ERROR(kmfh, ERR_get_error());
2581 ret = KMF_ERR_OCSP_BAD_ISSUER;
2582 goto end;
2583 }
2584
2585 if ((cert_stack = sk_X509_new_null()) == NULL) {
2586 ret = KMF_ERR_INTERNAL;
2587 goto end;
2588 }
2589
2590 if (sk_X509_push(cert_stack, issuer) == NULL) {
2591 ret = KMF_ERR_INTERNAL;
2592 goto end;
2593 }
2594
2595 ret = ocsp_find_signer(&signer, bs, cert_stack, NULL, 0);
2596 if (!ret) {
2597 /* can not find the signer */
2598 ret = KMF_ERR_OCSP_BAD_SIGNER;
2599 goto end;
2600 }
2601 }
2602
2603 /* Verify the signature of the response */
2604 skey = X509_get_pubkey(signer);
2605 if (skey == NULL) {
2606 ret = KMF_ERR_OCSP_BAD_SIGNER;
2607 goto end;
2608 }
2609
2610 ret = OCSP_BASICRESP_verify(bs, skey, 0);
2611 if (ret == 0) {
2612 ret = KMF_ERR_OCSP_RESPONSE_SIGNATURE;
2613 goto end;
2614 }
2615
2616 end:
2617 if (issuer != NULL) {
2618 X509_free(issuer);
2619 }
2620
2621 if (signer != NULL) {
2622 X509_free(signer);
2623 }
2624
2625 if (skey != NULL) {
2626 EVP_PKEY_free(skey);
2627 }
2628
2629 if (cert_stack != NULL) {
2630 sk_X509_free(cert_stack);
2631 }
2632
2633 return (ret);
2634 }
2635
2636
2637
2638 KMF_RETURN
2639 OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T handle,
2640 int numattr, KMF_ATTRIBUTE *attrlist)
2641 {
2642 KMF_RETURN ret = KMF_OK;
2643 BIO *derbio = NULL;
2644 OCSP_RESPONSE *resp = NULL;
2645 OCSP_BASICRESP *bs = NULL;
2646 OCSP_CERTID *id = NULL;
2647 OCSP_SINGLERESP *single = NULL;
2648 ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd;
2649 int index, status, reason;
2650 KMF_DATA *issuer_cert;
2651 KMF_DATA *user_cert;
2652 KMF_DATA *signer_cert;
2653 KMF_DATA *response;
2654 int *response_reason, *response_status, *cert_status;
2655 boolean_t ignore_response_sign = B_FALSE; /* default is FALSE */
2656 uint32_t response_lifetime;
2657
2658 issuer_cert = kmf_get_attr_ptr(KMF_ISSUER_CERT_DATA_ATTR,
2659 attrlist, numattr);
2660 if (issuer_cert == NULL)
2661 return (KMF_ERR_BAD_PARAMETER);
2662
2663 user_cert = kmf_get_attr_ptr(KMF_USER_CERT_DATA_ATTR,
2664 attrlist, numattr);
2665 if (user_cert == NULL)
2666 return (KMF_ERR_BAD_PARAMETER);
2667
2668 response = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_DATA_ATTR,
2669 attrlist, numattr);
2670 if (response == NULL)
2671 return (KMF_ERR_BAD_PARAMETER);
2672
2673 response_status = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_STATUS_ATTR,
2674 attrlist, numattr);
2675 if (response_status == NULL)
2676 return (KMF_ERR_BAD_PARAMETER);
2677
2678 response_reason = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_REASON_ATTR,
2679 attrlist, numattr);
2680 if (response_reason == NULL)
2681 return (KMF_ERR_BAD_PARAMETER);
2682
2683 cert_status = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_CERT_STATUS_ATTR,
2684 attrlist, numattr);
2685 if (cert_status == NULL)
2686 return (KMF_ERR_BAD_PARAMETER);
2687
2688 /* Read in the response */
2689 derbio = BIO_new_mem_buf(response->Data, response->Length);
2690 if (!derbio) {
2691 ret = KMF_ERR_MEMORY;
2692 return (ret);
2693 }
2694
2695 resp = d2i_OCSP_RESPONSE_bio(derbio, NULL);
2696 if (resp == NULL) {
2697 ret = KMF_ERR_OCSP_MALFORMED_RESPONSE;
2698 goto end;
2699 }
2700
2701 /* Check the response status */
2702 status = OCSP_response_status(resp);
2703 *response_status = status;
2704 if (status != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
2705 ret = KMF_ERR_OCSP_RESPONSE_STATUS;
2706 goto end;
2707 }
2708
2709 #ifdef DEBUG
2710 printf("Successfully checked the response file status.\n");
2711 #endif /* DEBUG */
2712
2713 /* Extract basic response */
2714 bs = OCSP_response_get1_basic(resp);
2715 if (bs == NULL) {
2716 ret = KMF_ERR_OCSP_NO_BASIC_RESPONSE;
2717 goto end;
2718 }
2719
2720 #ifdef DEBUG
2721 printf("Successfully retrieved the basic response.\n");
2722 #endif /* DEBUG */
2723
2724 /* Check the basic response signature if required */
2725 ret = kmf_get_attr(KMF_IGNORE_RESPONSE_SIGN_ATTR, attrlist, numattr,
2726 (void *)&ignore_response_sign, NULL);
2727 if (ret != KMF_OK)
2728 ret = KMF_OK;
2729
2730 signer_cert = kmf_get_attr_ptr(KMF_SIGNER_CERT_DATA_ATTR,
2731 attrlist, numattr);
2732
2733 if (ignore_response_sign == B_FALSE) {
2734 ret = check_response_signature(handle, bs,
2735 signer_cert, issuer_cert);
2736 if (ret != KMF_OK)
2737 goto end;
2738 }
2739
2740 #ifdef DEBUG
2741 printf("Successfully verified the response signature.\n");
2742 #endif /* DEBUG */
2743
2744 /* Create a certid for the certificate in question */
2745 ret = create_certid(handle, issuer_cert, user_cert, &id);
2746 if (ret != KMF_OK) {
2747 ret = KMF_ERR_OCSP_CERTID;
2748 goto end;
2749 }
2750
2751 #ifdef DEBUG
2752 printf("successfully created a certid for the cert.\n");
2753 #endif /* DEBUG */
2754
2755 /* Find the index of the single response for the certid */
2756 index = OCSP_resp_find(bs, id, -1);
2757 if (index < 0) {
2758 /* cound not find this certificate in the response */
2759 ret = KMF_ERR_OCSP_UNKNOWN_CERT;
2760 goto end;
2761 }
2762
2763 #ifdef DEBUG
2764 printf("Successfully found the single response index for the cert.\n");
2765 #endif /* DEBUG */
2766
2767 /* Retrieve the single response and get the cert status */
2768 single = OCSP_resp_get0(bs, index);
2769 status = OCSP_single_get0_status(single, &reason, &rev, &thisupd,
2770 &nextupd);
2771 if (status == V_OCSP_CERTSTATUS_GOOD) {
2772 *cert_status = OCSP_GOOD;
2773 } else if (status == V_OCSP_CERTSTATUS_UNKNOWN) {
2774 *cert_status = OCSP_UNKNOWN;
2775 } else { /* revoked */
2776 *cert_status = OCSP_REVOKED;
2777 *response_reason = reason;
2778 }
2779 ret = KMF_OK;
2780
2781 /* resp. time is optional, so we don't care about the return code. */
2782 (void) kmf_get_attr(KMF_RESPONSE_LIFETIME_ATTR, attrlist, numattr,
2783 (void *)&response_lifetime, NULL);
2784
2785 if (!OCSP_check_validity(thisupd, nextupd, 300,
2786 response_lifetime)) {
2787 ret = KMF_ERR_OCSP_STATUS_TIME_INVALID;
2788 goto end;
2789 }
2790
2791 #ifdef DEBUG
2792 printf("Successfully verify the time.\n");
2793 #endif /* DEBUG */
2794
2795 end:
2796 if (derbio != NULL)
2797 (void) BIO_free(derbio);
2798
2799 if (resp != NULL)
2800 OCSP_RESPONSE_free(resp);
2801
2802 if (bs != NULL)
2803 OCSP_BASICRESP_free(bs);
2804
2805 if (id != NULL)
2806 OCSP_CERTID_free(id);
2807
2808 return (ret);
2809 }
2810
2811 static KMF_RETURN
2812 fetch_key(KMF_HANDLE_T handle, char *path,
2813 KMF_KEY_CLASS keyclass, KMF_KEY_HANDLE *key)
2814 {
2815 KMF_RETURN rv = KMF_OK;
2816 EVP_PKEY *pkey = NULL;
2817 KMF_RAW_SYM_KEY *rkey = NULL;
2818
2819 if (keyclass == KMF_ASYM_PRI ||
2820 keyclass == KMF_ASYM_PUB) {
2821 pkey = openssl_load_key(handle, path);
2822 if (pkey == NULL) {
2823 return (KMF_ERR_KEY_NOT_FOUND);
2824 }
2825 if (key != NULL) {
2826 if (pkey->type == EVP_PKEY_RSA)
2827 key->keyalg = KMF_RSA;
2828 else if (pkey->type == EVP_PKEY_DSA)
2829 key->keyalg = KMF_DSA;
2830
2831 key->kstype = KMF_KEYSTORE_OPENSSL;
2832 key->keyclass = keyclass;
2833 key->keyp = (void *)pkey;
2834 key->israw = FALSE;
2835 if (path != NULL &&
2836 ((key->keylabel = strdup(path)) == NULL)) {
2837 EVP_PKEY_free(pkey);
2838 return (KMF_ERR_MEMORY);
2839 }
2840 } else {
2841 EVP_PKEY_free(pkey);
2842 pkey = NULL;
2843 }
2844 } else if (keyclass == KMF_SYMMETRIC) {
2845 KMF_ENCODE_FORMAT fmt;
2846 /*
2847 * If the file is a recognized format,
2848 * then it is NOT a symmetric key.
2849 */
2850 rv = kmf_get_file_format(path, &fmt);
2851 if (rv == KMF_OK || fmt != 0) {
2852 return (KMF_ERR_KEY_NOT_FOUND);
2853 } else if (rv == KMF_ERR_ENCODING) {
2854 /*
2855 * If we don't know the encoding,
2856 * it is probably a symmetric key.
2857 */
2858 rv = KMF_OK;
2859 } else if (rv == KMF_ERR_OPEN_FILE) {
2860 return (KMF_ERR_KEY_NOT_FOUND);
2861 }
2862
2863 if (key != NULL) {
2864 KMF_DATA keyvalue;
2865 rkey = malloc(sizeof (KMF_RAW_SYM_KEY));
2866 if (rkey == NULL) {
2867 rv = KMF_ERR_MEMORY;
2868 goto out;
2869 }
2870
2871 (void) memset(rkey, 0, sizeof (KMF_RAW_SYM_KEY));
2872 rv = kmf_read_input_file(handle, path, &keyvalue);
2873 if (rv != KMF_OK)
2874 goto out;
2875
2876 rkey->keydata.len = keyvalue.Length;
2877 rkey->keydata.val = keyvalue.Data;
2878
2879 key->kstype = KMF_KEYSTORE_OPENSSL;
2880 key->keyclass = keyclass;
2881 key->israw = TRUE;
2882 key->keyp = (void *)rkey;
2883 if (path != NULL &&
2884 ((key->keylabel = strdup(path)) == NULL)) {
2885 rv = KMF_ERR_MEMORY;
2886 }
2887 }
2888 }
2889 out:
2890 if (rv != KMF_OK) {
2891 if (rkey != NULL) {
2892 kmf_free_raw_sym_key(rkey);
2893 }
2894 if (pkey != NULL)
2895 EVP_PKEY_free(pkey);
2896
2897 if (key != NULL) {
2898 key->keyalg = KMF_KEYALG_NONE;
2899 key->keyclass = KMF_KEYCLASS_NONE;
2900 key->keyp = NULL;
2901 }
2902 }
2903
2904 return (rv);
2905 }
2906
2907 KMF_RETURN
2908 OpenSSL_FindKey(KMF_HANDLE_T handle,
2909 int numattr, KMF_ATTRIBUTE *attrlist)
2910 {
2911 KMF_RETURN rv = KMF_OK;
2912 char *fullpath = NULL;
2913 uint32_t maxkeys;
2914 KMF_KEY_HANDLE *key;
2915 uint32_t *numkeys;
2916 KMF_KEY_CLASS keyclass;
2917 KMF_RAW_KEY_DATA *rawkey;
2918 char *dirpath;
2919 char *keyfile;
2920
2921 if (handle == NULL)
2922 return (KMF_ERR_BAD_PARAMETER);
2923
2924 numkeys = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr);
2925 if (numkeys == NULL)
2926 return (KMF_ERR_BAD_PARAMETER);
2927
2928 rv = kmf_get_attr(KMF_KEYCLASS_ATTR, attrlist, numattr,
2929 (void *)&keyclass, NULL);
2930 if (rv != KMF_OK)
2931 return (KMF_ERR_BAD_PARAMETER);
2932
2933 if (keyclass != KMF_ASYM_PUB &&
2934 keyclass != KMF_ASYM_PRI &&
2935 keyclass != KMF_SYMMETRIC)
2936 return (KMF_ERR_BAD_KEY_CLASS);
2937
2938 dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
2939 keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr);
2940
2941 fullpath = get_fullpath(dirpath, keyfile);
2942
2943 if (fullpath == NULL)
2944 return (KMF_ERR_BAD_PARAMETER);
2945
2946 maxkeys = *numkeys;
2947 if (maxkeys == 0)
2948 maxkeys = 0xFFFFFFFF;
2949 *numkeys = 0;
2950
2951 key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
2952 /* it is okay to have "keys" contains NULL */
2953
2954 /*
2955 * The caller may want a list of the raw key data as well.
2956 * Useful for importing keys from a file into other keystores.
2957 */
2958 rawkey = kmf_get_attr_ptr(KMF_RAW_KEY_ATTR, attrlist, numattr);
2959
2960 if (isdir(fullpath)) {
2961 DIR *dirp;
2962 struct dirent *dp;
2963 int n = 0;
2964
2965 /* open all files in the directory and attempt to read them */
2966 if ((dirp = opendir(fullpath)) == NULL) {
2967 return (KMF_ERR_BAD_PARAMETER);
2968 }
2969 rewinddir(dirp);
2970 while ((dp = readdir(dirp)) != NULL && n < maxkeys) {
2971 if (strcmp(dp->d_name, ".") &&
2972 strcmp(dp->d_name, "..")) {
2973 char *fname;
2974
2975 fname = get_fullpath(fullpath,
2976 (char *)&dp->d_name);
2977
2978 rv = fetch_key(handle, fname,
2979 keyclass, key ? &key[n] : NULL);
2980
2981 if (rv == KMF_OK) {
2982 if (key != NULL && rawkey != NULL)
2983 rv = convertToRawKey(
2984 key[n].keyp, &rawkey[n]);
2985 n++;
2986 }
2987
2988 if (rv != KMF_OK || key == NULL)
2989 free(fname);
2990 }
2991 }
2992 (void) closedir(dirp);
2993 free(fullpath);
2994 (*numkeys) = n;
2995 } else {
2996 rv = fetch_key(handle, fullpath, keyclass, key);
2997 if (rv == KMF_OK)
2998 (*numkeys) = 1;
2999
3000 if (rv != KMF_OK || key == NULL)
3001 free(fullpath);
3002
3003 if (rv == KMF_OK && key != NULL && rawkey != NULL) {
3004 rv = convertToRawKey(key->keyp, rawkey);
3005 }
3006 }
3007
3008 if (rv == KMF_OK && (*numkeys) == 0)
3009 rv = KMF_ERR_KEY_NOT_FOUND;
3010 else if (rv == KMF_ERR_KEY_NOT_FOUND && (*numkeys) > 0)
3011 rv = KMF_OK;
3012
3013 return (rv);
3014 }
3015
3016 #define HANDLE_PK12_ERROR { \
3017 SET_ERROR(kmfh, ERR_get_error()); \
3018 rv = KMF_ERR_ENCODING; \
3019 goto out; \
3020 }
3021
3022 static int
3023 add_alias_to_bag(PKCS12_SAFEBAG *bag, X509 *xcert)
3024 {
3025 if (xcert != NULL && xcert->aux != NULL &&
3026 xcert->aux->alias != NULL) {
3027 if (PKCS12_add_friendlyname_asc(bag,
3028 (const char *)xcert->aux->alias->data,
3029 xcert->aux->alias->length) == 0)
3030 return (0);
3031 }
3032 return (1);
3033 }
3034
3035 static PKCS7 *
3036 add_cert_to_safe(X509 *sslcert, KMF_CREDENTIAL *cred,
3037 uchar_t *keyid, unsigned int keyidlen)
3038 {
3039 PKCS12_SAFEBAG *bag = NULL;
3040 PKCS7 *cert_authsafe = NULL;
3041 STACK_OF(PKCS12_SAFEBAG) *bag_stack;
3042
3043 bag_stack = sk_PKCS12_SAFEBAG_new_null();
3044 if (bag_stack == NULL)
3045 return (NULL);
3046
3047 /* Convert cert from X509 struct to PKCS#12 bag */
3048 bag = PKCS12_x5092certbag(sslcert);
3049 if (bag == NULL) {
3050 goto out;
3051 }
3052
3053 /* Add the key id to the certificate bag. */
3054 if (keyidlen > 0 && !PKCS12_add_localkeyid(bag, keyid, keyidlen)) {
3055 goto out;
3056 }
3057
3058 if (!add_alias_to_bag(bag, sslcert))
3059 goto out;
3060
3061 /* Pile it on the bag_stack. */
3062 if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag)) {
3063 goto out;
3064 }
3065 /* Turn bag_stack of certs into encrypted authsafe. */
3066 cert_authsafe = PKCS12_pack_p7encdata(
3067 NID_pbe_WithSHA1And40BitRC2_CBC,
3068 cred->cred, cred->credlen, NULL, 0,
3069 PKCS12_DEFAULT_ITER, bag_stack);
3070
3071 out:
3072 if (bag_stack != NULL)
3073 sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free);
3074
3075 return (cert_authsafe);
3076 }
3077
3078 static PKCS7 *
3079 add_key_to_safe(EVP_PKEY *pkey, KMF_CREDENTIAL *cred,
3080 uchar_t *keyid, unsigned int keyidlen,
3081 char *label, int label_len)
3082 {
3083 PKCS8_PRIV_KEY_INFO *p8 = NULL;
3084 STACK_OF(PKCS12_SAFEBAG) *bag_stack = NULL;
3085 PKCS12_SAFEBAG *bag = NULL;
3086 PKCS7 *key_authsafe = NULL;
3087
3088 p8 = EVP_PKEY2PKCS8(pkey);
3089 if (p8 == NULL) {
3090 return (NULL);
3091 }
3092 /* Put the shrouded key into a PKCS#12 bag. */
3093 bag = PKCS12_MAKE_SHKEYBAG(
3094 NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
3095 cred->cred, cred->credlen,
3096 NULL, 0, PKCS12_DEFAULT_ITER, p8);
3097
3098 /* Clean up the PKCS#8 shrouded key, don't need it now. */
3099 PKCS8_PRIV_KEY_INFO_free(p8);
3100 p8 = NULL;
3101
3102 if (bag == NULL) {
3103 return (NULL);
3104 }
3105 if (keyidlen && !PKCS12_add_localkeyid(bag, keyid, keyidlen))
3106 goto out;
3107 if (label != NULL && !PKCS12_add_friendlyname(bag, label, label_len))
3108 goto out;
3109
3110 /* Start a PKCS#12 safebag container for the private key. */
3111 bag_stack = sk_PKCS12_SAFEBAG_new_null();
3112 if (bag_stack == NULL)
3113 goto out;
3114
3115 /* Pile on the private key on the bag_stack. */
3116 if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag))
3117 goto out;
3118
3119 key_authsafe = PKCS12_pack_p7data(bag_stack);
3120
3121 out:
3122 if (bag_stack != NULL)
3123 sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free);
3124 bag_stack = NULL;
3125 return (key_authsafe);
3126 }
3127
3128 static EVP_PKEY *
3129 ImportRawRSAKey(KMF_RAW_RSA_KEY *key)
3130 {
3131 RSA *rsa = NULL;
3132 EVP_PKEY *newkey = NULL;
3133
3134 if ((rsa = RSA_new()) == NULL)
3135 return (NULL);
3136
3137 if ((rsa->n = BN_bin2bn(key->mod.val, key->mod.len, rsa->n)) == NULL)
3138 return (NULL);
3139
3140 if ((rsa->e = BN_bin2bn(key->pubexp.val, key->pubexp.len, rsa->e)) ==
3141 NULL)
3142 return (NULL);
3143
3144 if (key->priexp.val != NULL)
3145 if ((rsa->d = BN_bin2bn(key->priexp.val, key->priexp.len,
3146 rsa->d)) == NULL)
3147 return (NULL);
3148
3149 if (key->prime1.val != NULL)
3150 if ((rsa->p = BN_bin2bn(key->prime1.val, key->prime1.len,
3151 rsa->p)) == NULL)
3152 return (NULL);
3153
3154 if (key->prime2.val != NULL)
3155 if ((rsa->q = BN_bin2bn(key->prime2.val, key->prime2.len,
3156 rsa->q)) == NULL)
3157 return (NULL);
3158
3159 if (key->exp1.val != NULL)
3160 if ((rsa->dmp1 = BN_bin2bn(key->exp1.val, key->exp1.len,
3161 rsa->dmp1)) == NULL)
3162 return (NULL);
3163
3164 if (key->exp2.val != NULL)
3165 if ((rsa->dmq1 = BN_bin2bn(key->exp2.val, key->exp2.len,
3166 rsa->dmq1)) == NULL)
3167 return (NULL);
3168
3169 if (key->coef.val != NULL)
3170 if ((rsa->iqmp = BN_bin2bn(key->coef.val, key->coef.len,
3171 rsa->iqmp)) == NULL)
3172 return (NULL);
3173
3174 if ((newkey = EVP_PKEY_new()) == NULL)
3175 return (NULL);
3176
3177 (void) EVP_PKEY_set1_RSA(newkey, rsa);
3178
3179 /* The original key must be freed once here or it leaks memory */
3180 RSA_free(rsa);
3181
3182 return (newkey);
3183 }
3184
3185 static EVP_PKEY *
3186 ImportRawDSAKey(KMF_RAW_DSA_KEY *key)
3187 {
3188 DSA *dsa = NULL;
3189 EVP_PKEY *newkey = NULL;
3190
3191 if ((dsa = DSA_new()) == NULL)
3192 return (NULL);
3193
3194 if ((dsa->p = BN_bin2bn(key->prime.val, key->prime.len,
3195 dsa->p)) == NULL)
3196 return (NULL);
3197
3198 if ((dsa->q = BN_bin2bn(key->subprime.val, key->subprime.len,
3199 dsa->q)) == NULL)
3200 return (NULL);
3201
3202 if ((dsa->g = BN_bin2bn(key->base.val, key->base.len,
3203 dsa->g)) == NULL)
3204 return (NULL);
3205
3206 if ((dsa->priv_key = BN_bin2bn(key->value.val, key->value.len,
3207 dsa->priv_key)) == NULL)
3208 return (NULL);
3209
3210 if (key->pubvalue.val != NULL) {
3211 if ((dsa->pub_key = BN_bin2bn(key->pubvalue.val,
3212 key->pubvalue.len, dsa->pub_key)) == NULL)
3213 return (NULL);
3214 }
3215
3216 if ((newkey = EVP_PKEY_new()) == NULL)
3217 return (NULL);
3218
3219 (void) EVP_PKEY_set1_DSA(newkey, dsa);
3220
3221 /* The original key must be freed once here or it leaks memory */
3222 DSA_free(dsa);
3223 return (newkey);
3224 }
3225
3226 static EVP_PKEY *
3227 raw_key_to_pkey(KMF_KEY_HANDLE *key)
3228 {
3229 EVP_PKEY *pkey = NULL;
3230 KMF_RAW_KEY_DATA *rawkey;
3231 ASN1_TYPE *attr = NULL;
3232 KMF_RETURN ret;
3233
3234 if (key == NULL || !key->israw)
3235 return (NULL);
3236
3237 rawkey = (KMF_RAW_KEY_DATA *)key->keyp;
3238 if (rawkey->keytype == KMF_RSA) {
3239 pkey = ImportRawRSAKey(&rawkey->rawdata.rsa);
3240 } else if (rawkey->keytype == KMF_DSA) {
3241 pkey = ImportRawDSAKey(&rawkey->rawdata.dsa);
3242 } else if (rawkey->keytype == KMF_ECDSA) {
3243 /*
3244 * OpenSSL in Solaris does not support EC for
3245 * legal reasons
3246 */
3247 return (NULL);
3248 } else {
3249 /* wrong kind of key */
3250 return (NULL);
3251 }
3252
3253 if (rawkey->label != NULL) {
3254 if ((attr = ASN1_TYPE_new()) == NULL) {
3255 EVP_PKEY_free(pkey);
3256 return (NULL);
3257 }
3258 attr->value.bmpstring = ASN1_STRING_type_new(V_ASN1_BMPSTRING);
3259 (void) ASN1_STRING_set(attr->value.bmpstring, rawkey->label,
3260 strlen(rawkey->label));
3261 attr->type = V_ASN1_BMPSTRING;
3262 attr->value.ptr = (char *)attr->value.bmpstring;
3263 ret = set_pkey_attrib(pkey, attr, NID_friendlyName);
3264 if (ret != KMF_OK) {
3265 EVP_PKEY_free(pkey);
3266 ASN1_TYPE_free(attr);
3267 return (NULL);
3268 }
3269 }
3270 if (rawkey->id.Data != NULL) {
3271 if ((attr = ASN1_TYPE_new()) == NULL) {
3272 EVP_PKEY_free(pkey);
3273 return (NULL);
3274 }
3275 attr->value.octet_string =
3276 ASN1_STRING_type_new(V_ASN1_OCTET_STRING);
3277 attr->type = V_ASN1_OCTET_STRING;
3278 (void) ASN1_STRING_set(attr->value.octet_string,
3279 rawkey->id.Data, rawkey->id.Length);
3280 attr->value.ptr = (char *)attr->value.octet_string;
3281 ret = set_pkey_attrib(pkey, attr, NID_localKeyID);
3282 if (ret != KMF_OK) {
3283 EVP_PKEY_free(pkey);
3284 ASN1_TYPE_free(attr);
3285 return (NULL);
3286 }
3287 }
3288 return (pkey);
3289 }
3290
3291 /*
3292 * Search a list of private keys to find one that goes with the certificate.
3293 */
3294 static EVP_PKEY *
3295 find_matching_key(X509 *xcert, int numkeys, KMF_KEY_HANDLE *keylist)
3296 {
3297 int i;
3298 EVP_PKEY *pkey = NULL;
3299
3300 if (numkeys == 0 || keylist == NULL || xcert == NULL)
3301 return (NULL);
3302 for (i = 0; i < numkeys; i++) {
3303 if (keylist[i].israw)
3304 pkey = raw_key_to_pkey(&keylist[i]);
3305 else
3306 pkey = (EVP_PKEY *)keylist[i].keyp;
3307 if (pkey != NULL) {
3308 if (X509_check_private_key(xcert, pkey)) {
3309 return (pkey);
3310 } else {
3311 EVP_PKEY_free(pkey);
3312 pkey = NULL;
3313 }
3314 }
3315 }
3316 return (pkey);
3317 }
3318
3319 static KMF_RETURN
3320 local_export_pk12(KMF_HANDLE_T handle,
3321 KMF_CREDENTIAL *cred,
3322 int numcerts, KMF_X509_DER_CERT *certlist,
3323 int numkeys, KMF_KEY_HANDLE *keylist,
3324 char *filename)
3325 {
3326 KMF_RETURN rv = KMF_OK;
3327 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
3328 BIO *bio = NULL;
3329 PKCS7 *cert_authsafe = NULL;
3330 PKCS7 *key_authsafe = NULL;
3331 STACK_OF(PKCS7) *authsafe_stack = NULL;
3332 PKCS12 *p12_elem = NULL;
3333 int i;
3334
3335 if (numcerts == 0 && numkeys == 0)
3336 return (KMF_ERR_BAD_PARAMETER);
3337
3338 /*
3339 * Open the output file.
3340 */
3341 if ((bio = BIO_new_file(filename, "wb")) == NULL) {
3342 SET_ERROR(kmfh, ERR_get_error());
3343 rv = KMF_ERR_OPEN_FILE;
3344 goto cleanup;
3345 }
3346
3347 /* Start a PKCS#7 stack. */
3348 authsafe_stack = sk_PKCS7_new_null();
3349 if (authsafe_stack == NULL) {
3350 rv = KMF_ERR_MEMORY;
3351 goto cleanup;
3352 }
3353 if (numcerts > 0) {
3354 for (i = 0; rv == KMF_OK && i < numcerts; i++) {
3355 const uchar_t *p = certlist[i].certificate.Data;
3356 long len = certlist[i].certificate.Length;
3357 X509 *xcert = NULL;
3358 EVP_PKEY *pkey = NULL;
3359 unsigned char keyid[EVP_MAX_MD_SIZE];
3360 unsigned int keyidlen = 0;
3361
3362 xcert = d2i_X509(NULL, &p, len);
3363 if (xcert == NULL) {
3364 SET_ERROR(kmfh, ERR_get_error());
3365 rv = KMF_ERR_ENCODING;
3366 }
3367 if (certlist[i].kmf_private.label != NULL) {
3368 /* Set alias attribute */
3369 (void) X509_alias_set1(xcert,
3370 (uchar_t *)certlist[i].kmf_private.label,
3371 strlen(certlist[i].kmf_private.label));
3372 }
3373 /* Check if there is a key corresponding to this cert */
3374 pkey = find_matching_key(xcert, numkeys, keylist);
3375
3376 /*
3377 * If key is found, get fingerprint and create a
3378 * safebag.
3379 */
3380 if (pkey != NULL) {
3381 (void) X509_digest(xcert, EVP_sha1(),
3382 keyid, &keyidlen);
3383 key_authsafe = add_key_to_safe(pkey, cred,
3384 keyid, keyidlen,
3385 certlist[i].kmf_private.label,
3386 (certlist[i].kmf_private.label ?
3387 strlen(certlist[i].kmf_private.label) : 0));
3388
3389 if (key_authsafe == NULL) {
3390 X509_free(xcert);
3391 EVP_PKEY_free(pkey);
3392 goto cleanup;
3393 }
3394 /* Put the key safe into the Auth Safe */
3395 if (!sk_PKCS7_push(authsafe_stack,
3396 key_authsafe)) {
3397 X509_free(xcert);
3398 EVP_PKEY_free(pkey);
3399 goto cleanup;
3400 }
3401 }
3402
3403 /* create a certificate safebag */
3404 cert_authsafe = add_cert_to_safe(xcert, cred, keyid,
3405 keyidlen);
3406 if (cert_authsafe == NULL) {
3407 X509_free(xcert);
3408 EVP_PKEY_free(pkey);
3409 goto cleanup;
3410 }
3411 if (!sk_PKCS7_push(authsafe_stack, cert_authsafe)) {
3412 X509_free(xcert);
3413 EVP_PKEY_free(pkey);
3414 goto cleanup;
3415 }
3416
3417 X509_free(xcert);
3418 if (pkey)
3419 EVP_PKEY_free(pkey);
3420 }
3421 } else if (numcerts == 0 && numkeys > 0) {
3422 /*
3423 * If only adding keys to the file.
3424 */
3425 for (i = 0; i < numkeys; i++) {
3426 EVP_PKEY *pkey = NULL;
3427
3428 if (keylist[i].israw)
3429 pkey = raw_key_to_pkey(&keylist[i]);
3430 else
3431 pkey = (EVP_PKEY *)keylist[i].keyp;
3432
3433 if (pkey == NULL)
3434 continue;
3435
3436 key_authsafe = add_key_to_safe(pkey, cred,
3437 NULL, 0, NULL, 0);
3438
3439 if (key_authsafe == NULL) {
3440 EVP_PKEY_free(pkey);
3441 goto cleanup;
3442 }
3443 if (!sk_PKCS7_push(authsafe_stack, key_authsafe)) {
3444 EVP_PKEY_free(pkey);
3445 goto cleanup;
3446 }
3447 }
3448 }
3449 p12_elem = PKCS12_init(NID_pkcs7_data);
3450 if (p12_elem == NULL) {
3451 goto cleanup;
3452 }
3453
3454 /* Put the PKCS#7 stack into the PKCS#12 element. */
3455 if (!PKCS12_pack_authsafes(p12_elem, authsafe_stack)) {
3456 goto cleanup;
3457 }
3458
3459 /* Set the integrity MAC on the PKCS#12 element. */
3460 if (!PKCS12_set_mac(p12_elem, cred->cred, cred->credlen,
3461 NULL, 0, PKCS12_DEFAULT_ITER, NULL)) {
3462 goto cleanup;
3463 }
3464
3465 /* Write the PKCS#12 element to the export file. */
3466 if (!i2d_PKCS12_bio(bio, p12_elem)) {
3467 goto cleanup;
3468 }
3469 PKCS12_free(p12_elem);
3470
3471 cleanup:
3472 /* Clear away the PKCS#7 stack, we're done with it. */
3473 if (authsafe_stack)
3474 sk_PKCS7_pop_free(authsafe_stack, PKCS7_free);
3475
3476 if (bio != NULL)
3477 (void) BIO_free_all(bio);
3478
3479 return (rv);
3480 }
3481
3482 KMF_RETURN
3483 openssl_build_pk12(KMF_HANDLE_T handle, int numcerts,
3484 KMF_X509_DER_CERT *certlist, int numkeys, KMF_KEY_HANDLE *keylist,
3485 KMF_CREDENTIAL *p12cred, char *filename)
3486 {
3487 KMF_RETURN rv;
3488
3489 if (certlist == NULL && keylist == NULL)
3490 return (KMF_ERR_BAD_PARAMETER);
3491
3492 rv = local_export_pk12(handle, p12cred, numcerts, certlist,
3493 numkeys, keylist, filename);
3494
3495 return (rv);
3496 }
3497
3498 KMF_RETURN
3499 OpenSSL_ExportPK12(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
3500 {
3501 KMF_RETURN rv;
3502 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
3503 char *fullpath = NULL;
3504 char *dirpath = NULL;
3505 char *certfile = NULL;
3506 char *keyfile = NULL;
3507 char *filename = NULL;
3508 KMF_CREDENTIAL *p12cred = NULL;
3509 KMF_X509_DER_CERT certdata;
3510 KMF_KEY_HANDLE key;
3511 int gotkey = 0;
3512 int gotcert = 0;
3513
3514 if (handle == NULL)
3515 return (KMF_ERR_BAD_PARAMETER);
3516
3517 /*
3518 * First, find the certificate.
3519 */
3520 dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
3521 certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr);
3522 if (certfile != NULL) {
3523 fullpath = get_fullpath(dirpath, certfile);
3524 if (fullpath == NULL)
3525 return (KMF_ERR_BAD_PARAMETER);
3526
3527 if (isdir(fullpath)) {
3528 free(fullpath);
3529 return (KMF_ERR_AMBIGUOUS_PATHNAME);
3530 }
3531
3532 (void) memset(&certdata, 0, sizeof (certdata));
3533 rv = kmf_load_cert(kmfh, NULL, NULL, NULL, NULL,
3534 fullpath, &certdata.certificate);
3535 if (rv != KMF_OK)
3536 goto end;
3537
3538 gotcert++;
3539 certdata.kmf_private.keystore_type = KMF_KEYSTORE_OPENSSL;
3540 free(fullpath);
3541 }
3542
3543 /*
3544 * Now find the private key.
3545 */
3546 keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr);
3547 if (keyfile != NULL) {
3548 fullpath = get_fullpath(dirpath, keyfile);
3549 if (fullpath == NULL)
3550 return (KMF_ERR_BAD_PARAMETER);
3551
3552 if (isdir(fullpath)) {
3553 free(fullpath);
3554 return (KMF_ERR_AMBIGUOUS_PATHNAME);
3555 }
3556
3557 (void) memset(&key, 0, sizeof (KMF_KEY_HANDLE));
3558 rv = fetch_key(handle, fullpath, KMF_ASYM_PRI, &key);
3559 if (rv != KMF_OK)
3560 goto end;
3561 gotkey++;
3562 }
3563
3564 /*
3565 * Open the output file.
3566 */
3567 filename = kmf_get_attr_ptr(KMF_OUTPUT_FILENAME_ATTR, attrlist,
3568 numattr);
3569 if (filename == NULL) {
3570 rv = KMF_ERR_BAD_PARAMETER;
3571 goto end;
3572 }
3573
3574 /* Stick the key and the cert into a PKCS#12 file */
3575 p12cred = kmf_get_attr_ptr(KMF_PK12CRED_ATTR, attrlist, numattr);
3576 if (p12cred == NULL) {
3577 rv = KMF_ERR_BAD_PARAMETER;
3578 goto end;
3579 }
3580
3581 rv = local_export_pk12(handle, p12cred, 1, &certdata,
3582 1, &key, filename);
3583
3584 end:
3585 if (fullpath)
3586 free(fullpath);
3587
3588 if (gotcert)
3589 kmf_free_kmf_cert(handle, &certdata);
3590 if (gotkey)
3591 kmf_free_kmf_key(handle, &key);
3592 return (rv);
3593 }
3594
3595 /*
3596 * Helper function to extract keys and certificates from
3597 * a single PEM file. Typically the file should contain a
3598 * private key and an associated public key wrapped in an x509 cert.
3599 * However, the file may be just a list of X509 certs with no keys.
3600 */
3601 static KMF_RETURN
3602 extract_pem(KMF_HANDLE *kmfh,
3603 char *issuer, char *subject, KMF_BIGINT *serial,
3604 char *filename, CK_UTF8CHAR *pin,
3605 CK_ULONG pinlen, EVP_PKEY **priv_key, KMF_DATA **certs,
3606 int *numcerts)
3607 /* ARGSUSED6 */
3608 {
3609 KMF_RETURN rv = KMF_OK;
3610 FILE *fp;
3611 STACK_OF(X509_INFO) *x509_info_stack = NULL;
3612 int i, ncerts = 0, matchcerts = 0;
3613 EVP_PKEY *pkey = NULL;
3614 X509_INFO *info;
3615 X509 *x;
3616 X509_INFO **cert_infos = NULL;
3617 KMF_DATA *certlist = NULL;
3618
3619 if (priv_key)
3620 *priv_key = NULL;
3621 if (certs)
3622 *certs = NULL;
3623 fp = fopen(filename, "r");
3624 if (fp == NULL)
3625 return (KMF_ERR_OPEN_FILE);
3626
3627 x509_info_stack = PEM_X509_INFO_read(fp, NULL, NULL, pin);
3628 if (x509_info_stack == NULL) {
3629 (void) fclose(fp);
3630 return (KMF_ERR_ENCODING);
3631 }
3632 cert_infos = (X509_INFO **)malloc(sk_X509_INFO_num(x509_info_stack) *
3633 sizeof (X509_INFO *));
3634 if (cert_infos == NULL) {
3635 (void) fclose(fp);
3636 rv = KMF_ERR_MEMORY;
3637 goto err;
3638 }
3639
3640 for (i = 0; i < sk_X509_INFO_num(x509_info_stack); i++) {
3641 cert_infos[ncerts] = sk_X509_INFO_value(x509_info_stack, i);
3642 ncerts++;
3643 }
3644
3645 if (ncerts == 0) {
3646 (void) fclose(fp);
3647 rv = KMF_ERR_CERT_NOT_FOUND;
3648 goto err;
3649 }
3650
3651 if (priv_key != NULL) {
3652 rewind(fp);
3653 pkey = PEM_read_PrivateKey(fp, NULL, NULL, pin);
3654 }
3655 (void) fclose(fp);
3656
3657 x = cert_infos[ncerts - 1]->x509;
3658 /*
3659 * Make sure the private key matchs the last cert in the file.
3660 */
3661 if (pkey != NULL && !X509_check_private_key(x, pkey)) {
3662 EVP_PKEY_free(pkey);
3663 rv = KMF_ERR_KEY_MISMATCH;
3664 goto err;
3665 }
3666
3667 certlist = (KMF_DATA *)calloc(ncerts, sizeof (KMF_DATA));
3668 if (certlist == NULL) {
3669 if (pkey != NULL)
3670 EVP_PKEY_free(pkey);
3671 rv = KMF_ERR_MEMORY;
3672 goto err;
3673 }
3674
3675 /*
3676 * Convert all of the certs to DER format.
3677 */
3678 matchcerts = 0;
3679 for (i = 0; rv == KMF_OK && certs != NULL && i < ncerts; i++) {
3680 boolean_t match = FALSE;
3681 info = cert_infos[ncerts - 1 - i];
3682
3683 rv = check_cert(info->x509, issuer, subject, serial, &match);
3684 if (rv != KMF_OK || match != TRUE) {
3685 rv = KMF_OK;
3686 continue;
3687 }
3688
3689 rv = ssl_cert2KMFDATA(kmfh, info->x509,
3690 &certlist[matchcerts++]);
3691
3692 if (rv != KMF_OK) {
3693 int j;
3694 for (j = 0; j < matchcerts; j++)
3695 kmf_free_data(&certlist[j]);
3696 free(certlist);
3697 certlist = NULL;
3698 ncerts = matchcerts = 0;
3699 }
3700 }
3701
3702 if (numcerts != NULL)
3703 *numcerts = matchcerts;
3704
3705 if (certs != NULL)
3706 *certs = certlist;
3707 else if (certlist != NULL) {
3708 for (i = 0; i < ncerts; i++)
3709 kmf_free_data(&certlist[i]);
3710 free(certlist);
3711 certlist = NULL;
3712 }
3713
3714 if (priv_key == NULL && pkey != NULL)
3715 EVP_PKEY_free(pkey);
3716 else if (priv_key != NULL && pkey != NULL)
3717 *priv_key = pkey;
3718
3719 err:
3720 /* Cleanup the stack of X509 info records */
3721 for (i = 0; i < sk_X509_INFO_num(x509_info_stack); i++) {
3722 info = (X509_INFO *)sk_X509_INFO_value(x509_info_stack, i);
3723 X509_INFO_free(info);
3724 }
3725 if (x509_info_stack)
3726 sk_X509_INFO_free(x509_info_stack);
3727
3728 if (cert_infos != NULL)
3729 free(cert_infos);
3730
3731 return (rv);
3732 }
3733
3734 static KMF_RETURN
3735 openssl_parse_bags(STACK_OF(PKCS12_SAFEBAG) *bags, char *pin,
3736 STACK_OF(EVP_PKEY) *keys, STACK_OF(X509) *certs)
3737 {
3738 KMF_RETURN ret;
3739 int i;
3740
3741 for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) {
3742 PKCS12_SAFEBAG *bag = sk_PKCS12_SAFEBAG_value(bags, i);
3743 ret = openssl_parse_bag(bag, pin, (pin ? strlen(pin) : 0),
3744 keys, certs);
3745
3746 if (ret != KMF_OK)
3747 return (ret);
3748 }
3749
3750 return (ret);
3751 }
3752
3753 static KMF_RETURN
3754 set_pkey_attrib(EVP_PKEY *pkey, ASN1_TYPE *attrib, int nid)
3755 {
3756 X509_ATTRIBUTE *attr = NULL;
3757
3758 if (pkey == NULL || attrib == NULL)
3759 return (KMF_ERR_BAD_PARAMETER);
3760
3761 if (pkey->attributes == NULL) {
3762 pkey->attributes = sk_X509_ATTRIBUTE_new_null();
3763 if (pkey->attributes == NULL)
3764 return (KMF_ERR_MEMORY);
3765 }
3766 attr = X509_ATTRIBUTE_create(nid, attrib->type, attrib->value.ptr);
3767 if (attr != NULL) {
3768 int i;
3769 X509_ATTRIBUTE *a;
3770 for (i = 0;
3771 i < sk_X509_ATTRIBUTE_num(pkey->attributes); i++) {
3772 a = sk_X509_ATTRIBUTE_value(pkey->attributes, i);
3773 if (OBJ_obj2nid(a->object) == nid) {
3774 X509_ATTRIBUTE_free(a);
3775 sk_X509_ATTRIBUTE_set(pkey->attributes,
3776 i, attr);
3777 return (KMF_OK);
3778 }
3779 }
3780 if (sk_X509_ATTRIBUTE_push(pkey->attributes, attr) == NULL) {
3781 X509_ATTRIBUTE_free(attr);
3782 return (KMF_ERR_MEMORY);
3783 }
3784 } else {
3785 return (KMF_ERR_MEMORY);
3786 }
3787
3788 return (KMF_OK);
3789 }
3790
3791 static KMF_RETURN
3792 openssl_parse_bag(PKCS12_SAFEBAG *bag, char *pass, int passlen,
3793 STACK_OF(EVP_PKEY) *keylist, STACK_OF(X509) *certlist)
3794 {
3795 KMF_RETURN ret = KMF_OK;
3796 PKCS8_PRIV_KEY_INFO *p8 = NULL;
3797 EVP_PKEY *pkey = NULL;
3798 X509 *xcert = NULL;
3799 ASN1_TYPE *keyid = NULL;
3800 ASN1_TYPE *fname = NULL;
3801 uchar_t *data = NULL;
3802
3803 keyid = PKCS12_get_attr(bag, NID_localKeyID);
3804 fname = PKCS12_get_attr(bag, NID_friendlyName);
3805
3806 switch (M_PKCS12_bag_type(bag)) {
3807 case NID_keyBag:
3808 if (keylist == NULL)
3809 goto end;
3810 pkey = EVP_PKCS82PKEY(bag->value.keybag);
3811 if (pkey == NULL)
3812 ret = KMF_ERR_PKCS12_FORMAT;
3813
3814 break;
3815 case NID_pkcs8ShroudedKeyBag:
3816 if (keylist == NULL)
3817 goto end;
3818 p8 = M_PKCS12_decrypt_skey(bag, pass, passlen);
3819 if (p8 == NULL)
3820 return (KMF_ERR_AUTH_FAILED);
3821 pkey = EVP_PKCS82PKEY(p8);
3822 PKCS8_PRIV_KEY_INFO_free(p8);
3823 if (pkey == NULL)
3824 ret = KMF_ERR_PKCS12_FORMAT;
3825 break;
3826 case NID_certBag:
3827 if (certlist == NULL)
3828 goto end;
3829 if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate)
3830 return (KMF_ERR_PKCS12_FORMAT);
3831 xcert = M_PKCS12_certbag2x509(bag);
3832 if (xcert == NULL) {
3833 ret = KMF_ERR_PKCS12_FORMAT;
3834 goto end;
3835 }
3836 if (keyid != NULL) {
3837 if (X509_keyid_set1(xcert,
3838 keyid->value.octet_string->data,
3839 keyid->value.octet_string->length) == 0) {
3840 ret = KMF_ERR_PKCS12_FORMAT;
3841 goto end;
3842 }
3843 }
3844 if (fname != NULL) {
3845 int len, r;
3846 len = ASN1_STRING_to_UTF8(&data,
3847 fname->value.asn1_string);
3848 if (len > 0 && data != NULL) {
3849 r = X509_alias_set1(xcert, data, len);
3850 if (r == NULL) {
3851 ret = KMF_ERR_PKCS12_FORMAT;
3852 goto end;
3853 }
3854 } else {
3855 ret = KMF_ERR_PKCS12_FORMAT;
3856 goto end;
3857 }
3858 }
3859 if (sk_X509_push(certlist, xcert) == 0)
3860 ret = KMF_ERR_MEMORY;
3861 else
3862 xcert = NULL;
3863 break;
3864 case NID_safeContentsBag:
3865 return (openssl_parse_bags(bag->value.safes, pass,
3866 keylist, certlist));
3867 default:
3868 ret = KMF_ERR_PKCS12_FORMAT;
3869 break;
3870 }
3871
3872 /*
3873 * Set the ID and/or FriendlyName attributes on the key.
3874 * If converting to PKCS11 objects, these can translate to CKA_ID
3875 * and CKA_LABEL values.
3876 */
3877 if (pkey != NULL && ret == KMF_OK) {
3878 ASN1_TYPE *attr = NULL;
3879 if (keyid != NULL && keyid->type == V_ASN1_OCTET_STRING) {
3880 if ((attr = ASN1_TYPE_new()) == NULL)
3881 return (KMF_ERR_MEMORY);
3882 attr->value.octet_string =
3883 ASN1_STRING_dup(keyid->value.octet_string);
3884 attr->type = V_ASN1_OCTET_STRING;
3885 attr->value.ptr = (char *)attr->value.octet_string;
3886 ret = set_pkey_attrib(pkey, attr, NID_localKeyID);
3887 OPENSSL_free(attr);
3888 }
3889
3890 if (ret == KMF_OK && fname != NULL &&
3891 fname->type == V_ASN1_BMPSTRING) {
3892 if ((attr = ASN1_TYPE_new()) == NULL)
3893 return (KMF_ERR_MEMORY);
3894 attr->value.bmpstring =
3895 ASN1_STRING_dup(fname->value.bmpstring);
3896 attr->type = V_ASN1_BMPSTRING;
3897 attr->value.ptr = (char *)attr->value.bmpstring;
3898 ret = set_pkey_attrib(pkey, attr, NID_friendlyName);
3899 OPENSSL_free(attr);
3900 }
3901
3902 if (ret == KMF_OK && keylist != NULL &&
3903 sk_EVP_PKEY_push(keylist, pkey) == 0)
3904 ret = KMF_ERR_MEMORY;
3905 }
3906 if (ret == KMF_OK && keylist != NULL)
3907 pkey = NULL;
3908 end:
3909 if (pkey != NULL)
3910 EVP_PKEY_free(pkey);
3911 if (xcert != NULL)
3912 X509_free(xcert);
3913 if (data != NULL)
3914 OPENSSL_free(data);
3915
3916 return (ret);
3917 }
3918
3919 static KMF_RETURN
3920 openssl_pkcs12_parse(PKCS12 *p12, char *pin,
3921 STACK_OF(EVP_PKEY) *keys,
3922 STACK_OF(X509) *certs,
3923 STACK_OF(X509) *ca)
3924 /* ARGSUSED3 */
3925 {
3926 KMF_RETURN ret = KMF_OK;
3927 STACK_OF(PKCS7) *asafes = NULL;
3928 STACK_OF(PKCS12_SAFEBAG) *bags = NULL;
3929 int i, bagnid;
3930 PKCS7 *p7;
3931
3932 if (p12 == NULL || (keys == NULL && certs == NULL))
3933 return (KMF_ERR_BAD_PARAMETER);
3934
3935 if (pin == NULL || *pin == NULL) {
3936 if (PKCS12_verify_mac(p12, NULL, 0)) {
3937 pin = NULL;
3938 } else if (PKCS12_verify_mac(p12, "", 0)) {
3939 pin = "";
3940 } else {
3941 return (KMF_ERR_AUTH_FAILED);
3942 }
3943 } else if (!PKCS12_verify_mac(p12, pin, -1)) {
3944 return (KMF_ERR_AUTH_FAILED);
3945 }
3946
3947 if ((asafes = PKCS12_unpack_authsafes(p12)) == NULL)
3948 return (KMF_ERR_PKCS12_FORMAT);
3949
3950 for (i = 0; ret == KMF_OK && i < sk_PKCS7_num(asafes); i++) {
3951 bags = NULL;
3952 p7 = sk_PKCS7_value(asafes, i);
3953 bagnid = OBJ_obj2nid(p7->type);
3954
3955 if (bagnid == NID_pkcs7_data) {
3956 bags = PKCS12_unpack_p7data(p7);
3957 } else if (bagnid == NID_pkcs7_encrypted) {
3958 bags = PKCS12_unpack_p7encdata(p7, pin,
3959 (pin ? strlen(pin) : 0));
3960 } else {
3961 continue;
3962 }
3963 if (bags == NULL) {
3964 ret = KMF_ERR_PKCS12_FORMAT;
3965 goto out;
3966 }
3967
3968 if (openssl_parse_bags(bags, pin, keys, certs) != KMF_OK)
3969 ret = KMF_ERR_PKCS12_FORMAT;
3970
3971 sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
3972 }
3973 out:
3974 if (asafes != NULL)
3975 sk_PKCS7_pop_free(asafes, PKCS7_free);
3976
3977 return (ret);
3978 }
3979
3980 /*
3981 * Helper function to decrypt and parse PKCS#12 import file.
3982 */
3983 static KMF_RETURN
3984 extract_pkcs12(BIO *fbio, CK_UTF8CHAR *pin, CK_ULONG pinlen,
3985 STACK_OF(EVP_PKEY) **priv_key, STACK_OF(X509) **certs,
3986 STACK_OF(X509) **ca)
3987 /* ARGSUSED2 */
3988 {
3989 PKCS12 *pk12, *pk12_tmp;
3990 STACK_OF(EVP_PKEY) *pkeylist = NULL;
3991 STACK_OF(X509) *xcertlist = NULL;
3992 STACK_OF(X509) *cacertlist = NULL;
3993
3994 if ((pk12 = PKCS12_new()) == NULL) {
3995 return (KMF_ERR_MEMORY);
3996 }
3997
3998 if ((pk12_tmp = d2i_PKCS12_bio(fbio, &pk12)) == NULL) {
3999 /* This is ok; it seems to mean there is no more to read. */
4000 if (ERR_GET_LIB(ERR_peek_error()) == ERR_LIB_ASN1 &&
4001 ERR_GET_REASON(ERR_peek_error()) == ASN1_R_HEADER_TOO_LONG)
4002 goto end_extract_pkcs12;
4003
4004 PKCS12_free(pk12);
4005 return (KMF_ERR_PKCS12_FORMAT);
4006 }
4007 pk12 = pk12_tmp;
4008
4009 xcertlist = sk_X509_new_null();
4010 if (xcertlist == NULL) {
4011 PKCS12_free(pk12);
4012 return (KMF_ERR_MEMORY);
4013 }
4014 pkeylist = sk_EVP_PKEY_new_null();
4015 if (pkeylist == NULL) {
4016 sk_X509_pop_free(xcertlist, X509_free);
4017 PKCS12_free(pk12);
4018 return (KMF_ERR_MEMORY);
4019 }
4020
4021 if (openssl_pkcs12_parse(pk12, (char *)pin, pkeylist, xcertlist,
4022 cacertlist) != KMF_OK) {
4023 sk_X509_pop_free(xcertlist, X509_free);
4024 sk_EVP_PKEY_pop_free(pkeylist, EVP_PKEY_free);
4025 PKCS12_free(pk12);
4026 return (KMF_ERR_PKCS12_FORMAT);
4027 }
4028
4029 if (priv_key && pkeylist)
4030 *priv_key = pkeylist;
4031 else if (pkeylist)
4032 sk_EVP_PKEY_pop_free(pkeylist, EVP_PKEY_free);
4033 if (certs && xcertlist)
4034 *certs = xcertlist;
4035 else if (xcertlist)
4036 sk_X509_pop_free(xcertlist, X509_free);
4037 if (ca && cacertlist)
4038 *ca = cacertlist;
4039 else if (cacertlist)
4040 sk_X509_pop_free(cacertlist, X509_free);
4041
4042 end_extract_pkcs12:
4043
4044 PKCS12_free(pk12);
4045 return (KMF_OK);
4046 }
4047
4048 static KMF_RETURN
4049 sslBN2KMFBN(BIGNUM *from, KMF_BIGINT *to)
4050 {
4051 KMF_RETURN rv = KMF_OK;
4052 uint32_t sz;
4053
4054 sz = BN_num_bytes(from);
4055 to->val = (uchar_t *)malloc(sz);
4056 if (to->val == NULL)
4057 return (KMF_ERR_MEMORY);
4058
4059 if ((to->len = BN_bn2bin(from, to->val)) != sz) {
4060 free(to->val);
4061 to->val = NULL;
4062 to->len = 0;
4063 rv = KMF_ERR_MEMORY;
4064 }
4065
4066 return (rv);
4067 }
4068
4069 static KMF_RETURN
4070 exportRawRSAKey(RSA *rsa, KMF_RAW_KEY_DATA *key)
4071 {
4072 KMF_RETURN rv;
4073 KMF_RAW_RSA_KEY *kmfkey = &key->rawdata.rsa;
4074
4075 (void) memset(kmfkey, 0, sizeof (KMF_RAW_RSA_KEY));
4076 if ((rv = sslBN2KMFBN(rsa->n, &kmfkey->mod)) != KMF_OK)
4077 goto cleanup;
4078
4079 if ((rv = sslBN2KMFBN(rsa->e, &kmfkey->pubexp)) != KMF_OK)
4080 goto cleanup;
4081
4082 if (rsa->d != NULL)
4083 if ((rv = sslBN2KMFBN(rsa->d, &kmfkey->priexp)) != KMF_OK)
4084 goto cleanup;
4085
4086 if (rsa->p != NULL)
4087 if ((rv = sslBN2KMFBN(rsa->p, &kmfkey->prime1)) != KMF_OK)
4088 goto cleanup;
4089
4090 if (rsa->q != NULL)
4091 if ((rv = sslBN2KMFBN(rsa->q, &kmfkey->prime2)) != KMF_OK)
4092 goto cleanup;
4093
4094 if (rsa->dmp1 != NULL)
4095 if ((rv = sslBN2KMFBN(rsa->dmp1, &kmfkey->exp1)) != KMF_OK)
4096 goto cleanup;
4097
4098 if (rsa->dmq1 != NULL)
4099 if ((rv = sslBN2KMFBN(rsa->dmq1, &kmfkey->exp2)) != KMF_OK)
4100 goto cleanup;
4101
4102 if (rsa->iqmp != NULL)
4103 if ((rv = sslBN2KMFBN(rsa->iqmp, &kmfkey->coef)) != KMF_OK)
4104 goto cleanup;
4105 cleanup:
4106 if (rv != KMF_OK)
4107 kmf_free_raw_key(key);
4108 else
4109 key->keytype = KMF_RSA;
4110
4111 /*
4112 * Free the reference to this key, SSL will not actually free
4113 * the memory until the refcount == 0, so this is safe.
4114 */
4115 RSA_free(rsa);
4116
4117 return (rv);
4118 }
4119
4120 static KMF_RETURN
4121 exportRawDSAKey(DSA *dsa, KMF_RAW_KEY_DATA *key)
4122 {
4123 KMF_RETURN rv;
4124 KMF_RAW_DSA_KEY *kmfkey = &key->rawdata.dsa;
4125
4126 (void) memset(kmfkey, 0, sizeof (KMF_RAW_DSA_KEY));
4127 if ((rv = sslBN2KMFBN(dsa->p, &kmfkey->prime)) != KMF_OK)
4128 goto cleanup;
4129
4130 if ((rv = sslBN2KMFBN(dsa->q, &kmfkey->subprime)) != KMF_OK)
4131 goto cleanup;
4132
4133 if ((rv = sslBN2KMFBN(dsa->g, &kmfkey->base)) != KMF_OK)
4134 goto cleanup;
4135
4136 if ((rv = sslBN2KMFBN(dsa->priv_key, &kmfkey->value)) != KMF_OK)
4137 goto cleanup;
4138
4139 cleanup:
4140 if (rv != KMF_OK)
4141 kmf_free_raw_key(key);
4142 else
4143 key->keytype = KMF_DSA;
4144
4145 /*
4146 * Free the reference to this key, SSL will not actually free
4147 * the memory until the refcount == 0, so this is safe.
4148 */
4149 DSA_free(dsa);
4150
4151 return (rv);
4152 }
4153
4154 static KMF_RETURN
4155 add_cert_to_list(KMF_HANDLE *kmfh, X509 *sslcert,
4156 KMF_X509_DER_CERT **certlist, int *ncerts)
4157 {
4158 KMF_RETURN rv = KMF_OK;
4159 KMF_X509_DER_CERT *list = (*certlist);
4160 KMF_X509_DER_CERT cert;
4161 int n = (*ncerts);
4162
4163 if (list == NULL) {
4164 list = (KMF_X509_DER_CERT *)malloc(sizeof (KMF_X509_DER_CERT));
4165 } else {
4166 list = (KMF_X509_DER_CERT *)realloc(list,
4167 sizeof (KMF_X509_DER_CERT) * (n + 1));
4168 }
4169
4170 if (list == NULL)
4171 return (KMF_ERR_MEMORY);
4172
4173 (void) memset(&cert, 0, sizeof (cert));
4174 rv = ssl_cert2KMFDATA(kmfh, sslcert, &cert.certificate);
4175 if (rv == KMF_OK) {
4176 int len = 0;
4177 /* Get the alias name for the cert if there is one */
4178 char *a = (char *)X509_alias_get0(sslcert, &len);
4179 if (a != NULL)
4180 cert.kmf_private.label = strdup(a);
4181 cert.kmf_private.keystore_type = KMF_KEYSTORE_OPENSSL;
4182
4183 list[n] = cert;
4184 (*ncerts) = n + 1;
4185
4186 *certlist = list;
4187 } else {
4188 free(list);
4189 }
4190
4191 return (rv);
4192 }
4193
4194 static KMF_RETURN
4195 add_key_to_list(KMF_RAW_KEY_DATA **keylist,
4196 KMF_RAW_KEY_DATA *newkey, int *nkeys)
4197 {
4198 KMF_RAW_KEY_DATA *list = (*keylist);
4199 int n = (*nkeys);
4200
4201 if (list == NULL) {
4202 list = (KMF_RAW_KEY_DATA *)malloc(sizeof (KMF_RAW_KEY_DATA));
4203 } else {
4204 list = (KMF_RAW_KEY_DATA *)realloc(list,
4205 sizeof (KMF_RAW_KEY_DATA) * (n + 1));
4206 }
4207
4208 if (list == NULL)
4209 return (KMF_ERR_MEMORY);
4210
4211 list[n] = *newkey;
4212 (*nkeys) = n + 1;
4213
4214 *keylist = list;
4215
4216 return (KMF_OK);
4217 }
4218
4219 static X509_ATTRIBUTE *
4220 find_attr(STACK_OF(X509_ATTRIBUTE) *attrs, int nid)
4221 {
4222 X509_ATTRIBUTE *a;
4223 int i;
4224
4225 if (attrs == NULL)
4226 return (NULL);
4227
4228 for (i = 0; i < sk_X509_ATTRIBUTE_num(attrs); i++) {
4229 a = sk_X509_ATTRIBUTE_value(attrs, i);
4230 if (OBJ_obj2nid(a->object) == nid)
4231 return (a);
4232 }
4233 return (NULL);
4234 }
4235
4236 static KMF_RETURN
4237 convertToRawKey(EVP_PKEY *pkey, KMF_RAW_KEY_DATA *key)
4238 {
4239 KMF_RETURN rv = KMF_OK;
4240 X509_ATTRIBUTE *attr;
4241
4242 if (pkey == NULL || key == NULL)
4243 return (KMF_ERR_BAD_PARAMETER);
4244 /* Convert SSL key to raw key */
4245 switch (pkey->type) {
4246 case EVP_PKEY_RSA:
4247 rv = exportRawRSAKey(EVP_PKEY_get1_RSA(pkey),
4248 key);
4249 if (rv != KMF_OK)
4250 return (rv);
4251 break;
4252 case EVP_PKEY_DSA:
4253 rv = exportRawDSAKey(EVP_PKEY_get1_DSA(pkey),
4254 key);
4255 if (rv != KMF_OK)
4256 return (rv);
4257 break;
4258 default:
4259 return (KMF_ERR_BAD_PARAMETER);
4260 }
4261 /*
4262 * If friendlyName, add it to record.
4263 */
4264 attr = find_attr(pkey->attributes, NID_friendlyName);
4265 if (attr != NULL) {
4266 ASN1_TYPE *ty = NULL;
4267 int numattr = sk_ASN1_TYPE_num(attr->value.set);
4268 if (attr->single == 0 && numattr > 0) {
4269 ty = sk_ASN1_TYPE_value(attr->value.set, 0);
4270 }
4271 if (ty != NULL) {
4272 #if OPENSSL_VERSION_NUMBER < 0x10000000L
4273 key->label = uni2asc(ty->value.bmpstring->data,
4274 ty->value.bmpstring->length);
4275 #else
4276 key->label = OPENSSL_uni2asc(ty->value.bmpstring->data,
4277 ty->value.bmpstring->length);
4278 #endif
4279 }
4280 } else {
4281 key->label = NULL;
4282 }
4283
4284 /*
4285 * If KeyID, add it to record as a KMF_DATA object.
4286 */
4287 attr = find_attr(pkey->attributes, NID_localKeyID);
4288 if (attr != NULL) {
4289 ASN1_TYPE *ty = NULL;
4290 int numattr = sk_ASN1_TYPE_num(attr->value.set);
4291 if (attr->single == 0 && numattr > 0) {
4292 ty = sk_ASN1_TYPE_value(attr->value.set, 0);
4293 }
4294 key->id.Data = (uchar_t *)malloc(
4295 ty->value.octet_string->length);
4296 if (key->id.Data == NULL)
4297 return (KMF_ERR_MEMORY);
4298 (void) memcpy(key->id.Data, ty->value.octet_string->data,
4299 ty->value.octet_string->length);
4300 key->id.Length = ty->value.octet_string->length;
4301 } else {
4302 (void) memset(&key->id, 0, sizeof (KMF_DATA));
4303 }
4304
4305 return (rv);
4306 }
4307
4308 static KMF_RETURN
4309 convertPK12Objects(
4310 KMF_HANDLE *kmfh,
4311 STACK_OF(EVP_PKEY) *sslkeys,
4312 STACK_OF(X509) *sslcert,
4313 STACK_OF(X509) *sslcacerts,
4314 KMF_RAW_KEY_DATA **keylist, int *nkeys,
4315 KMF_X509_DER_CERT **certlist, int *ncerts)
4316 {
4317 KMF_RETURN rv = KMF_OK;
4318 KMF_RAW_KEY_DATA key;
4319 int i;
4320
4321 for (i = 0; sslkeys != NULL && i < sk_EVP_PKEY_num(sslkeys); i++) {
4322 EVP_PKEY *pkey = sk_EVP_PKEY_value(sslkeys, i);
4323 rv = convertToRawKey(pkey, &key);
4324 if (rv == KMF_OK)
4325 rv = add_key_to_list(keylist, &key, nkeys);
4326
4327 if (rv != KMF_OK)
4328 return (rv);
4329 }
4330
4331 /* Now add the certificate to the certlist */
4332 for (i = 0; sslcert != NULL && i < sk_X509_num(sslcert); i++) {
4333 X509 *cert = sk_X509_value(sslcert, i);
4334 rv = add_cert_to_list(kmfh, cert, certlist, ncerts);
4335 if (rv != KMF_OK)
4336 return (rv);
4337 }
4338
4339 /* Also add any included CA certs to the list */
4340 for (i = 0; sslcacerts != NULL && i < sk_X509_num(sslcacerts); i++) {
4341 X509 *c;
4342 /*
4343 * sk_X509_value() is macro that embeds a cast to (X509 *).
4344 * Here it translates into ((X509 *)sk_value((ca), (i))).
4345 * Lint is complaining about the embedded casting, and
4346 * to fix it, you need to fix openssl header files.
4347 */
4348 c = sk_X509_value(sslcacerts, i);
4349
4350 /* Now add the ca cert to the certlist */
4351 rv = add_cert_to_list(kmfh, c, certlist, ncerts);
4352 if (rv != KMF_OK)
4353 return (rv);
4354 }
4355 return (rv);
4356 }
4357
4358 KMF_RETURN
4359 openssl_import_objects(KMF_HANDLE *kmfh,
4360 char *filename, KMF_CREDENTIAL *cred,
4361 KMF_X509_DER_CERT **certlist, int *ncerts,
4362 KMF_RAW_KEY_DATA **keylist, int *nkeys)
4363 {
4364 KMF_RETURN rv = KMF_OK;
4365 KMF_ENCODE_FORMAT format;
4366 BIO *bio = NULL;
4367 STACK_OF(EVP_PKEY) *privkeys = NULL;
4368 STACK_OF(X509) *certs = NULL;
4369 STACK_OF(X509) *cacerts = NULL;
4370
4371 /*
4372 * auto-detect the file format, regardless of what
4373 * the 'format' parameters in the params say.
4374 */
4375 rv = kmf_get_file_format(filename, &format);
4376 if (rv != KMF_OK) {
4377 return (rv);
4378 }
4379
4380 /* This function only works for PEM or PKCS#12 files */
4381 if (format != KMF_FORMAT_PEM &&
4382 format != KMF_FORMAT_PEM_KEYPAIR &&
4383 format != KMF_FORMAT_PKCS12)
4384 return (KMF_ERR_ENCODING);
4385
4386 *certlist = NULL;
4387 *keylist = NULL;
4388 *ncerts = 0;
4389 *nkeys = 0;
4390
4391 if (format == KMF_FORMAT_PKCS12) {
4392 bio = BIO_new_file(filename, "rb");
4393 if (bio == NULL) {
4394 SET_ERROR(kmfh, ERR_get_error());
4395 rv = KMF_ERR_OPEN_FILE;
4396 goto end;
4397 }
4398
4399 rv = extract_pkcs12(bio, (uchar_t *)cred->cred,
4400 (uint32_t)cred->credlen, &privkeys, &certs, &cacerts);
4401
4402 if (rv == KMF_OK)
4403 /* Convert keys and certs to exportable format */
4404 rv = convertPK12Objects(kmfh, privkeys, certs, cacerts,
4405 keylist, nkeys, certlist, ncerts);
4406 } else {
4407 EVP_PKEY *pkey;
4408 KMF_DATA *certdata = NULL;
4409 KMF_X509_DER_CERT *kmfcerts = NULL;
4410 int i;
4411 rv = extract_pem(kmfh, NULL, NULL, NULL, filename,
4412 (uchar_t *)cred->cred, (uint32_t)cred->credlen,
4413 &pkey, &certdata, ncerts);
4414
4415 /* Reached end of import file? */
4416 if (rv == KMF_OK && pkey != NULL) {
4417 privkeys = sk_EVP_PKEY_new_null();
4418 if (privkeys == NULL) {
4419 rv = KMF_ERR_MEMORY;
4420 goto end;
4421 }
4422 (void) sk_EVP_PKEY_push(privkeys, pkey);
4423 /* convert the certificate list here */
4424 if (*ncerts > 0 && certlist != NULL) {
4425 kmfcerts = (KMF_X509_DER_CERT *)calloc(*ncerts,
4426 sizeof (KMF_X509_DER_CERT));
4427 if (kmfcerts == NULL) {
4428 rv = KMF_ERR_MEMORY;
4429 goto end;
4430 }
4431 for (i = 0; i < *ncerts; i++) {
4432 kmfcerts[i].certificate = certdata[i];
4433 kmfcerts[i].kmf_private.keystore_type =
4434 KMF_KEYSTORE_OPENSSL;
4435 }
4436 *certlist = kmfcerts;
4437 }
4438 /*
4439 * Convert keys to exportable format, the certs
4440 * are already OK.
4441 */
4442 rv = convertPK12Objects(kmfh, privkeys, NULL, NULL,
4443 keylist, nkeys, NULL, NULL);
4444 }
4445 }
4446 end:
4447 if (bio != NULL)
4448 (void) BIO_free(bio);
4449
4450 if (privkeys)
4451 sk_EVP_PKEY_pop_free(privkeys, EVP_PKEY_free);
4452 if (certs)
4453 sk_X509_pop_free(certs, X509_free);
4454 if (cacerts)
4455 sk_X509_pop_free(cacerts, X509_free);
4456
4457 return (rv);
4458 }
4459
4460 static KMF_RETURN
4461 create_deskey(DES_cblock **deskey)
4462 {
4463 DES_cblock *key;
4464
4465 key = (DES_cblock *) malloc(sizeof (DES_cblock));
4466 if (key == NULL) {
4467 return (KMF_ERR_MEMORY);
4468 }
4469
4470 if (DES_random_key(key) == 0) {
4471 free(key);
4472 return (KMF_ERR_KEYGEN_FAILED);
4473 }
4474
4475 *deskey = key;
4476 return (KMF_OK);
4477 }
4478
4479 #define KEYGEN_RETRY 3
4480 #define DES3_KEY_SIZE 24
4481
4482 static KMF_RETURN
4483 create_des3key(unsigned char **des3key)
4484 {
4485 KMF_RETURN ret = KMF_OK;
4486 DES_cblock *deskey1 = NULL;
4487 DES_cblock *deskey2 = NULL;
4488 DES_cblock *deskey3 = NULL;
4489 unsigned char *newkey = NULL;
4490 int retry;
4491
4492 if ((newkey = malloc(DES3_KEY_SIZE)) == NULL) {
4493 return (KMF_ERR_MEMORY);
4494 }
4495
4496 /* create the 1st DES key */
4497 if ((ret = create_deskey(&deskey1)) != KMF_OK) {
4498 goto out;
4499 }
4500
4501 /*
4502 * Create the 2nd DES key and make sure its value is different
4503 * from the 1st DES key.
4504 */
4505 retry = 0;
4506 do {
4507 if (deskey2 != NULL) {
4508 free(deskey2);
4509 deskey2 = NULL;
4510 }
4511
4512 if ((ret = create_deskey(&deskey2)) != KMF_OK) {
4513 goto out;
4514 }
4515
4516 if (memcmp((const void *) deskey1, (const void *) deskey2, 8)
4517 == 0) {
4518 ret = KMF_ERR_KEYGEN_FAILED;
4519 retry++;
4520 }
4521 } while (ret == KMF_ERR_KEYGEN_FAILED && retry < KEYGEN_RETRY);
4522
4523 if (ret != KMF_OK) {
4524 goto out;
4525 }
4526
4527 /*
4528 * Create the 3rd DES key and make sure its value is different
4529 * from the 2nd DES key.
4530 */
4531 retry = 0;
4532 do {
4533 if (deskey3 != NULL) {
4534 free(deskey3);
4535 deskey3 = NULL;
4536 }
4537
4538 if ((ret = create_deskey(&deskey3)) != KMF_OK) {
4539 goto out;
4540 }
4541
4542 if (memcmp((const void *)deskey2, (const void *)deskey3, 8)
4543 == 0) {
4544 ret = KMF_ERR_KEYGEN_FAILED;
4545 retry++;
4546 }
4547 } while (ret == KMF_ERR_KEYGEN_FAILED && retry < KEYGEN_RETRY);
4548
4549 if (ret != KMF_OK) {
4550 goto out;
4551 }
4552
4553 /* Concatenate 3 DES keys into a DES3 key */
4554 (void) memcpy((void *)newkey, (const void *)deskey1, 8);
4555 (void) memcpy((void *)(newkey + 8), (const void *)deskey2, 8);
4556 (void) memcpy((void *)(newkey + 16), (const void *)deskey3, 8);
4557 *des3key = newkey;
4558
4559 out:
4560 if (deskey1 != NULL)
4561 free(deskey1);
4562
4563 if (deskey2 != NULL)
4564 free(deskey2);
4565
4566 if (deskey3 != NULL)
4567 free(deskey3);
4568
4569 if (ret != KMF_OK && newkey != NULL)
4570 free(newkey);
4571
4572 return (ret);
4573 }
4574
4575 KMF_RETURN
4576 OpenSSL_CreateSymKey(KMF_HANDLE_T handle,
4577 int numattr, KMF_ATTRIBUTE *attrlist)
4578 {
4579 KMF_RETURN ret = KMF_OK;
4580 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
4581 char *fullpath = NULL;
4582 KMF_RAW_SYM_KEY *rkey = NULL;
4583 DES_cblock *deskey = NULL;
4584 unsigned char *des3key = NULL;
4585 unsigned char *random = NULL;
4586 int fd = -1;
4587 KMF_KEY_HANDLE *symkey;
4588 KMF_KEY_ALG keytype;
4589 uint32_t keylen;
4590 uint32_t keylen_size = sizeof (keylen);
4591 char *dirpath;
4592 char *keyfile;
4593
4594 if (kmfh == NULL)
4595 return (KMF_ERR_UNINITIALIZED);
4596
4597 symkey = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
4598 if (symkey == NULL)
4599 return (KMF_ERR_BAD_PARAMETER);
4600
4601 dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
4602
4603 keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr);
4604 if (keyfile == NULL)
4605 return (KMF_ERR_BAD_PARAMETER);
4606
4607 ret = kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr,
4608 (void *)&keytype, NULL);
4609 if (ret != KMF_OK)
4610 return (KMF_ERR_BAD_PARAMETER);
4611
4612 ret = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr,
4613 &keylen, &keylen_size);
4614 if (ret == KMF_ERR_ATTR_NOT_FOUND &&
4615 (keytype == KMF_DES || keytype == KMF_DES3))
4616 /* keylength is not required for DES and 3DES */
4617 ret = KMF_OK;
4618 if (ret != KMF_OK)
4619 return (KMF_ERR_BAD_PARAMETER);
4620
4621 fullpath = get_fullpath(dirpath, keyfile);
4622 if (fullpath == NULL)
4623 return (KMF_ERR_BAD_PARAMETER);
4624
4625 /* If the requested file exists, return an error */
4626 if (test_for_file(fullpath, 0400) == 1) {
4627 free(fullpath);
4628 return (KMF_ERR_DUPLICATE_KEYFILE);
4629 }
4630
4631 fd = open(fullpath, O_CREAT|O_TRUNC|O_RDWR, 0400);
4632 if (fd == -1) {
4633 ret = KMF_ERR_OPEN_FILE;
4634 goto out;
4635 }
4636
4637 rkey = malloc(sizeof (KMF_RAW_SYM_KEY));
4638 if (rkey == NULL) {
4639 ret = KMF_ERR_MEMORY;
4640 goto out;
4641 }
4642 (void) memset(rkey, 0, sizeof (KMF_RAW_SYM_KEY));
4643
4644 if (keytype == KMF_DES) {
4645 if ((ret = create_deskey(&deskey)) != KMF_OK) {
4646 goto out;
4647 }
4648 rkey->keydata.val = (uchar_t *)deskey;
4649 rkey->keydata.len = 8;
4650
4651 symkey->keyalg = KMF_DES;
4652
4653 } else if (keytype == KMF_DES3) {
4654 if ((ret = create_des3key(&des3key)) != KMF_OK) {
4655 goto out;
4656 }
4657 rkey->keydata.val = (uchar_t *)des3key;
4658 rkey->keydata.len = DES3_KEY_SIZE;
4659 symkey->keyalg = KMF_DES3;
4660
4661 } else if (keytype == KMF_AES || keytype == KMF_RC4 ||
4662 keytype == KMF_GENERIC_SECRET) {
4663 int bytes;
4664
4665 if (keylen % 8 != 0) {
4666 ret = KMF_ERR_BAD_KEY_SIZE;
4667 goto out;
4668 }
4669
4670 if (keytype == KMF_AES) {
4671 if (keylen != 128 &&
4672 keylen != 192 &&
4673 keylen != 256) {
4674 ret = KMF_ERR_BAD_KEY_SIZE;
4675 goto out;
4676 }
4677 }
4678
4679 bytes = keylen/8;
4680 random = malloc(bytes);
4681 if (random == NULL) {
4682 ret = KMF_ERR_MEMORY;
4683 goto out;
4684 }
4685 if (RAND_bytes(random, bytes) != 1) {
4686 ret = KMF_ERR_KEYGEN_FAILED;
4687 goto out;
4688 }
4689
4690 rkey->keydata.val = (uchar_t *)random;
4691 rkey->keydata.len = bytes;
4692 symkey->keyalg = keytype;
4693
4694 } else {
4695 ret = KMF_ERR_BAD_KEY_TYPE;
4696 goto out;
4697 }
4698
4699 (void) write(fd, (const void *) rkey->keydata.val, rkey->keydata.len);
4700
4701 symkey->kstype = KMF_KEYSTORE_OPENSSL;
4702 symkey->keyclass = KMF_SYMMETRIC;
4703 symkey->keylabel = (char *)fullpath;
4704 symkey->israw = TRUE;
4705 symkey->keyp = rkey;
4706
4707 out:
4708 if (fd != -1)
4709 (void) close(fd);
4710
4711 if (ret != KMF_OK && fullpath != NULL) {
4712 free(fullpath);
4713 }
4714 if (ret != KMF_OK) {
4715 kmf_free_raw_sym_key(rkey);
4716 symkey->keyp = NULL;
4717 symkey->keyalg = KMF_KEYALG_NONE;
4718 }
4719
4720 return (ret);
4721 }
4722
4723 /*
4724 * Check a file to see if it is a CRL file with PEM or DER format.
4725 * If success, return its format in the "pformat" argument.
4726 */
4727 KMF_RETURN
4728 OpenSSL_IsCRLFile(KMF_HANDLE_T handle, char *filename, int *pformat)
4729 {
4730 KMF_RETURN ret = KMF_OK;
4731 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
4732 BIO *bio = NULL;
4733 X509_CRL *xcrl = NULL;
4734
4735 if (filename == NULL) {
4736 return (KMF_ERR_BAD_PARAMETER);
4737 }
4738
4739 bio = BIO_new_file(filename, "rb");
4740 if (bio == NULL) {
4741 SET_ERROR(kmfh, ERR_get_error());
4742 ret = KMF_ERR_OPEN_FILE;
4743 goto out;
4744 }
4745
4746 if ((xcrl = PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL)) != NULL) {
4747 *pformat = KMF_FORMAT_PEM;
4748 goto out;
4749 }
4750 (void) BIO_free(bio);
4751
4752 /*
4753 * Now try to read it as raw DER data.
4754 */
4755 bio = BIO_new_file(filename, "rb");
4756 if (bio == NULL) {
4757 SET_ERROR(kmfh, ERR_get_error());
4758 ret = KMF_ERR_OPEN_FILE;
4759 goto out;
4760 }
4761
4762 if ((xcrl = d2i_X509_CRL_bio(bio, NULL)) != NULL) {
4763 *pformat = KMF_FORMAT_ASN1;
4764 } else {
4765 ret = KMF_ERR_BAD_CRLFILE;
4766 }
4767
4768 out:
4769 if (bio != NULL)
4770 (void) BIO_free(bio);
4771
4772 if (xcrl != NULL)
4773 X509_CRL_free(xcrl);
4774
4775 return (ret);
4776 }
4777
4778 KMF_RETURN
4779 OpenSSL_GetSymKeyValue(KMF_HANDLE_T handle, KMF_KEY_HANDLE *symkey,
4780 KMF_RAW_SYM_KEY *rkey)
4781 {
4782 KMF_RETURN rv = KMF_OK;
4783 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
4784 KMF_DATA keyvalue;
4785
4786 if (kmfh == NULL)
4787 return (KMF_ERR_UNINITIALIZED);
4788
4789 if (symkey == NULL || rkey == NULL)
4790 return (KMF_ERR_BAD_PARAMETER);
4791 else if (symkey->keyclass != KMF_SYMMETRIC)
4792 return (KMF_ERR_BAD_KEY_CLASS);
4793
4794 if (symkey->israw) {
4795 KMF_RAW_SYM_KEY *rawkey = (KMF_RAW_SYM_KEY *)symkey->keyp;
4796
4797 if (rawkey == NULL ||
4798 rawkey->keydata.val == NULL ||
4799 rawkey->keydata.len == 0)
4800 return (KMF_ERR_BAD_KEYHANDLE);
4801
4802 rkey->keydata.len = rawkey->keydata.len;
4803 if ((rkey->keydata.val = malloc(rkey->keydata.len)) == NULL)
4804 return (KMF_ERR_MEMORY);
4805 (void) memcpy(rkey->keydata.val, rawkey->keydata.val,
4806 rkey->keydata.len);
4807 } else {
4808 rv = kmf_read_input_file(handle, symkey->keylabel, &keyvalue);
4809 if (rv != KMF_OK)
4810 return (rv);
4811 rkey->keydata.len = keyvalue.Length;
4812 rkey->keydata.val = keyvalue.Data;
4813 }
4814
4815 return (rv);
4816 }
4817
4818 /*
4819 * substitute for the unsafe access(2) function.
4820 * If the file in question already exists, return 1.
4821 * else 0. If an error occurs during testing (other
4822 * than EEXIST), return -1.
4823 */
4824 static int
4825 test_for_file(char *filename, mode_t mode)
4826 {
4827 int fd;
4828
4829 /*
4830 * Try to create the file with the EXCL flag.
4831 * The call should fail if the file exists.
4832 */
4833 fd = open(filename, O_WRONLY|O_CREAT|O_EXCL, mode);
4834 if (fd == -1 && errno == EEXIST)
4835 return (1);
4836 else if (fd == -1) /* some other error */
4837 return (-1);
4838
4839 /* The file did NOT exist. Delete the testcase. */
4840 (void) close(fd);
4841 (void) unlink(filename);
4842 return (0);
4843 }
4844
4845 KMF_RETURN
4846 OpenSSL_StoreKey(KMF_HANDLE_T handle, int numattr,
4847 KMF_ATTRIBUTE *attrlist)
4848 {
4849 KMF_RETURN rv = KMF_OK;
4850 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
4851 KMF_KEY_HANDLE *pubkey = NULL, *prikey = NULL;
4852 KMF_RAW_KEY_DATA *rawkey;
4853 EVP_PKEY *pkey = NULL;
4854 KMF_ENCODE_FORMAT format = KMF_FORMAT_PEM;
4855 KMF_CREDENTIAL cred = {NULL, 0};
4856 BIO *out = NULL;
4857 int keys = 0;
4858 char *fullpath = NULL;
4859 char *keyfile = NULL;
4860 char *dirpath = NULL;
4861
4862 pubkey = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attrlist, numattr);
4863 if (pubkey != NULL)
4864 keys++;
4865
4866 prikey = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attrlist, numattr);
4867 if (prikey != NULL)
4868 keys++;
4869
4870 rawkey = kmf_get_attr_ptr(KMF_RAW_KEY_ATTR, attrlist, numattr);
4871 if (rawkey != NULL)
4872 keys++;
4873
4874 /*
4875 * Exactly 1 type of key must be passed to this function.
4876 */
4877 if (keys != 1)
4878 return (KMF_ERR_BAD_PARAMETER);
4879
4880 keyfile = (char *)kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist,
4881 numattr);
4882 if (keyfile == NULL)
4883 return (KMF_ERR_BAD_PARAMETER);
4884
4885 dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
4886
4887 fullpath = get_fullpath(dirpath, keyfile);
4888
4889 /* Once we have the full path, we don't need the pieces */
4890 if (fullpath == NULL)
4891 return (KMF_ERR_BAD_PARAMETER);
4892
4893 /* If the requested file exists, return an error */
4894 if (test_for_file(fullpath, 0400) == 1) {
4895 free(fullpath);
4896 return (KMF_ERR_DUPLICATE_KEYFILE);
4897 }
4898
4899 rv = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr,
4900 &format, NULL);
4901 if (rv != KMF_OK)
4902 /* format is optional. */
4903 rv = KMF_OK;
4904
4905 /* CRED is not required for OpenSSL files */
4906 (void) kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr,
4907 &cred, NULL);
4908
4909 /* Store the private key to the keyfile */
4910 out = BIO_new_file(fullpath, "wb");
4911 if (out == NULL) {
4912 SET_ERROR(kmfh, ERR_get_error());
4913 rv = KMF_ERR_OPEN_FILE;
4914 goto end;
4915 }
4916
4917 if (prikey != NULL && prikey->keyp != NULL) {
4918 if (prikey->keyalg == KMF_RSA ||
4919 prikey->keyalg == KMF_DSA) {
4920 pkey = (EVP_PKEY *)prikey->keyp;
4921
4922 rv = ssl_write_key(kmfh, format,
4923 out, &cred, pkey, TRUE);
4924
4925 if (rv == KMF_OK && prikey->keylabel == NULL) {
4926 prikey->keylabel = strdup(fullpath);
4927 if (prikey->keylabel == NULL)
4928 rv = KMF_ERR_MEMORY;
4929 }
4930 }
4931 } else if (pubkey != NULL && pubkey->keyp != NULL) {
4932 if (pubkey->keyalg == KMF_RSA ||
4933 pubkey->keyalg == KMF_DSA) {
4934 pkey = (EVP_PKEY *)pubkey->keyp;
4935
4936 rv = ssl_write_key(kmfh, format,
4937 out, &cred, pkey, FALSE);
4938
4939 if (rv == KMF_OK && pubkey->keylabel == NULL) {
4940 pubkey->keylabel = strdup(fullpath);
4941 if (pubkey->keylabel == NULL)
4942 rv = KMF_ERR_MEMORY;
4943 }
4944 }
4945 } else if (rawkey != NULL) {
4946 if (rawkey->keytype == KMF_RSA) {
4947 pkey = ImportRawRSAKey(&rawkey->rawdata.rsa);
4948 } else if (rawkey->keytype == KMF_DSA) {
4949 pkey = ImportRawDSAKey(&rawkey->rawdata.dsa);
4950 } else {
4951 rv = KMF_ERR_BAD_PARAMETER;
4952 }
4953 if (pkey != NULL) {
4954 KMF_KEY_CLASS kclass = KMF_ASYM_PRI;
4955
4956 rv = kmf_get_attr(KMF_KEYCLASS_ATTR, attrlist, numattr,
4957 (void *)&kclass, NULL);
4958 if (rv != KMF_OK)
4959 rv = KMF_OK;
4960 rv = ssl_write_key(kmfh, format, out,
4961 &cred, pkey, (kclass == KMF_ASYM_PRI));
4962 EVP_PKEY_free(pkey);
4963 }
4964 }
4965
4966 end:
4967
4968 if (out)
4969 (void) BIO_free(out);
4970
4971
4972 if (rv == KMF_OK)
4973 (void) chmod(fullpath, 0400);
4974
4975 free(fullpath);
4976 return (rv);
4977 }
4978
4979 KMF_RETURN
4980 OpenSSL_ImportCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
4981 {
4982 KMF_RETURN ret = KMF_OK;
4983 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
4984 X509_CRL *xcrl = NULL;
4985 X509 *xcert = NULL;
4986 EVP_PKEY *pkey;
4987 KMF_ENCODE_FORMAT format;
4988 BIO *in = NULL, *out = NULL;
4989 int openssl_ret = 0;
4990 KMF_ENCODE_FORMAT outformat;
4991 boolean_t crlcheck = FALSE;
4992 char *certfile, *dirpath, *crlfile, *incrl, *outcrl, *outcrlfile;
4993
4994 if (numattr == 0 || attrlist == NULL) {
4995 return (KMF_ERR_BAD_PARAMETER);
4996 }
4997
4998 /* CRL check is optional */
4999 (void) kmf_get_attr(KMF_CRL_CHECK_ATTR, attrlist, numattr,
5000 &crlcheck, NULL);
5001
5002 certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr);
5003 if (crlcheck == B_TRUE && certfile == NULL) {
5004 return (KMF_ERR_BAD_CERTFILE);
5005 }
5006
5007 dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
5008 incrl = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR, attrlist, numattr);
5009 outcrl = kmf_get_attr_ptr(KMF_CRL_OUTFILE_ATTR, attrlist, numattr);
5010
5011 crlfile = get_fullpath(dirpath, incrl);
5012
5013 if (crlfile == NULL)
5014 return (KMF_ERR_BAD_CRLFILE);
5015
5016 outcrlfile = get_fullpath(dirpath, outcrl);
5017 if (outcrlfile == NULL)
5018 return (KMF_ERR_BAD_CRLFILE);
5019
5020 if (isdir(outcrlfile)) {
5021 free(outcrlfile);
5022 return (KMF_ERR_BAD_CRLFILE);
5023 }
5024
5025 ret = kmf_is_crl_file(handle, crlfile, &format);
5026 if (ret != KMF_OK) {
5027 free(outcrlfile);
5028 return (ret);
5029 }
5030
5031 in = BIO_new_file(crlfile, "rb");
5032 if (in == NULL) {
5033 SET_ERROR(kmfh, ERR_get_error());
5034 ret = KMF_ERR_OPEN_FILE;
5035 goto end;
5036 }
5037
5038 if (format == KMF_FORMAT_ASN1) {
5039 xcrl = d2i_X509_CRL_bio(in, NULL);
5040 } else if (format == KMF_FORMAT_PEM) {
5041 xcrl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
5042 }
5043
5044 if (xcrl == NULL) {
5045 SET_ERROR(kmfh, ERR_get_error());
5046 ret = KMF_ERR_BAD_CRLFILE;
5047 goto end;
5048 }
5049
5050 /* If bypasscheck is specified, no need to verify. */
5051 if (crlcheck == B_FALSE)
5052 goto output;
5053
5054 ret = kmf_is_cert_file(handle, certfile, &format);
5055 if (ret != KMF_OK)
5056 goto end;
5057
5058 /* Read in the CA cert file and convert to X509 */
5059 if (BIO_read_filename(in, certfile) <= 0) {
5060 SET_ERROR(kmfh, ERR_get_error());
5061 ret = KMF_ERR_OPEN_FILE;
5062 goto end;
5063 }
5064
5065 if (format == KMF_FORMAT_ASN1) {
5066 xcert = d2i_X509_bio(in, NULL);
5067 } else if (format == KMF_FORMAT_PEM) {
5068 xcert = PEM_read_bio_X509(in, NULL, NULL, NULL);
5069 } else {
5070 ret = KMF_ERR_BAD_CERT_FORMAT;
5071 goto end;
5072 }
5073
5074 if (xcert == NULL) {
5075 SET_ERROR(kmfh, ERR_get_error());
5076 ret = KMF_ERR_BAD_CERT_FORMAT;
5077 goto end;
5078 }
5079 /* Now get the public key from the CA cert */
5080 pkey = X509_get_pubkey(xcert);
5081 if (pkey == NULL) {
5082 SET_ERROR(kmfh, ERR_get_error());
5083 ret = KMF_ERR_BAD_CERTFILE;
5084 goto end;
5085 }
5086
5087 /* Verify the CRL with the CA's public key */
5088 openssl_ret = X509_CRL_verify(xcrl, pkey);
5089 EVP_PKEY_free(pkey);
5090 if (openssl_ret > 0) {
5091 ret = KMF_OK; /* verify succeed */
5092 } else {
5093 SET_ERROR(kmfh, openssl_ret);
5094 ret = KMF_ERR_BAD_CRLFILE;
5095 }
5096
5097 output:
5098 ret = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr,
5099 &outformat, NULL);
5100 if (ret != KMF_OK) {
5101 ret = KMF_OK;
5102 outformat = KMF_FORMAT_PEM;
5103 }
5104
5105 out = BIO_new_file(outcrlfile, "wb");
5106 if (out == NULL) {
5107 SET_ERROR(kmfh, ERR_get_error());
5108 ret = KMF_ERR_OPEN_FILE;
5109 goto end;
5110 }
5111
5112 if (outformat == KMF_FORMAT_ASN1) {
5113 openssl_ret = (int)i2d_X509_CRL_bio(out, xcrl);
5114 } else if (outformat == KMF_FORMAT_PEM) {
5115 openssl_ret = PEM_write_bio_X509_CRL(out, xcrl);
5116 } else {
5117 ret = KMF_ERR_BAD_PARAMETER;
5118 goto end;
5119 }
5120
5121 if (openssl_ret <= 0) {
5122 SET_ERROR(kmfh, ERR_get_error());
5123 ret = KMF_ERR_WRITE_FILE;
5124 } else {
5125 ret = KMF_OK;
5126 }
5127
5128 end:
5129 if (xcrl != NULL)
5130 X509_CRL_free(xcrl);
5131
5132 if (xcert != NULL)
5133 X509_free(xcert);
5134
5135 if (in != NULL)
5136 (void) BIO_free(in);
5137
5138 if (out != NULL)
5139 (void) BIO_free(out);
5140
5141 if (outcrlfile != NULL)
5142 free(outcrlfile);
5143
5144 return (ret);
5145 }
5146
5147 KMF_RETURN
5148 OpenSSL_ListCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
5149 {
5150 KMF_RETURN ret = KMF_OK;
5151 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
5152 X509_CRL *x = NULL;
5153 KMF_ENCODE_FORMAT format;
5154 char *crlfile = NULL;
5155 BIO *in = NULL;
5156 BIO *mem = NULL;
5157 long len;
5158 char *memptr;
5159 char *data = NULL;
5160 char **crldata;
5161 char *crlfilename, *dirpath;
5162
5163 if (numattr == 0 || attrlist == NULL) {
5164 return (KMF_ERR_BAD_PARAMETER);
5165 }
5166 crlfilename = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR,
5167 attrlist, numattr);
5168 if (crlfilename == NULL)
5169 return (KMF_ERR_BAD_CRLFILE);
5170
5171 crldata = (char **)kmf_get_attr_ptr(KMF_CRL_DATA_ATTR,
5172 attrlist, numattr);
5173
5174 if (crldata == NULL)
5175 return (KMF_ERR_BAD_PARAMETER);
5176
5177 dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
5178
5179 crlfile = get_fullpath(dirpath, crlfilename);
5180
5181 if (crlfile == NULL)
5182 return (KMF_ERR_BAD_CRLFILE);
5183
5184 if (isdir(crlfile)) {
5185 free(crlfile);
5186 return (KMF_ERR_BAD_CRLFILE);
5187 }
5188
5189 ret = kmf_is_crl_file(handle, crlfile, &format);
5190 if (ret != KMF_OK) {
5191 free(crlfile);
5192 return (ret);
5193 }
5194
5195 if (bio_err == NULL)
5196 bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
5197
5198 in = BIO_new_file(crlfile, "rb");
5199 if (in == NULL) {
5200 SET_ERROR(kmfh, ERR_get_error());
5201 ret = KMF_ERR_OPEN_FILE;
5202 goto end;
5203 }
5204
5205 if (format == KMF_FORMAT_ASN1) {
5206 x = d2i_X509_CRL_bio(in, NULL);
5207 } else if (format == KMF_FORMAT_PEM) {
5208 x = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
5209 }
5210
5211 if (x == NULL) { /* should not happen */
5212 SET_ERROR(kmfh, ERR_get_error());
5213 ret = KMF_ERR_OPEN_FILE;
5214 goto end;
5215 }
5216
5217 mem = BIO_new(BIO_s_mem());
5218 if (mem == NULL) {
5219 SET_ERROR(kmfh, ERR_get_error());
5220 ret = KMF_ERR_MEMORY;
5221 goto end;
5222 }
5223
5224 (void) X509_CRL_print(mem, x);
5225 len = BIO_get_mem_data(mem, &memptr);
5226 if (len <= 0) {
5227 SET_ERROR(kmfh, ERR_get_error());
5228 ret = KMF_ERR_MEMORY;
5229 goto end;
5230 }
5231
5232 data = malloc(len + 1);
5233 if (data == NULL) {
5234 ret = KMF_ERR_MEMORY;
5235 goto end;
5236 }
5237
5238 (void) memcpy(data, memptr, len);
5239 data[len] = '\0';
5240 *crldata = data;
5241
5242 end:
5243 if (x != NULL)
5244 X509_CRL_free(x);
5245
5246 if (crlfile != NULL)
5247 free(crlfile);
5248
5249 if (in != NULL)
5250 (void) BIO_free(in);
5251
5252 if (mem != NULL)
5253 (void) BIO_free(mem);
5254
5255 return (ret);
5256 }
5257
5258 KMF_RETURN
5259 OpenSSL_DeleteCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
5260 {
5261 KMF_RETURN ret = KMF_OK;
5262 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
5263 KMF_ENCODE_FORMAT format;
5264 char *crlfile = NULL;
5265 BIO *in = NULL;
5266 char *crlfilename, *dirpath;
5267
5268 if (numattr == 0 || attrlist == NULL) {
5269 return (KMF_ERR_BAD_PARAMETER);
5270 }
5271
5272 crlfilename = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR,
5273 attrlist, numattr);
5274
5275 if (crlfilename == NULL)
5276 return (KMF_ERR_BAD_CRLFILE);
5277
5278 dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
5279
5280 crlfile = get_fullpath(dirpath, crlfilename);
5281
5282 if (crlfile == NULL)
5283 return (KMF_ERR_BAD_CRLFILE);
5284
5285 if (isdir(crlfile)) {
5286 ret = KMF_ERR_BAD_CRLFILE;
5287 goto end;
5288 }
5289
5290 ret = kmf_is_crl_file(handle, crlfile, &format);
5291 if (ret != KMF_OK)
5292 goto end;
5293
5294 if (unlink(crlfile) != 0) {
5295 SET_SYS_ERROR(kmfh, errno);
5296 ret = KMF_ERR_INTERNAL;
5297 goto end;
5298 }
5299
5300 end:
5301 if (in != NULL)
5302 (void) BIO_free(in);
5303 if (crlfile != NULL)
5304 free(crlfile);
5305
5306 return (ret);
5307 }
5308
5309 KMF_RETURN
5310 OpenSSL_FindCertInCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
5311 {
5312 KMF_RETURN ret = KMF_OK;
5313 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
5314 KMF_ENCODE_FORMAT format;
5315 BIO *in = NULL;
5316 X509 *xcert = NULL;
5317 X509_CRL *xcrl = NULL;
5318 STACK_OF(X509_REVOKED) *revoke_stack = NULL;
5319 X509_REVOKED *revoke;
5320 int i;
5321 char *crlfilename, *crlfile, *dirpath, *certfile;
5322
5323 if (numattr == 0 || attrlist == NULL) {
5324 return (KMF_ERR_BAD_PARAMETER);
5325 }
5326
5327 crlfilename = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR,
5328 attrlist, numattr);
5329
5330 if (crlfilename == NULL)
5331 return (KMF_ERR_BAD_CRLFILE);
5332
5333 certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr);
5334 if (certfile == NULL)
5335 return (KMF_ERR_BAD_CRLFILE);
5336
5337 dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
5338
5339 crlfile = get_fullpath(dirpath, crlfilename);
5340
5341 if (crlfile == NULL)
5342 return (KMF_ERR_BAD_CRLFILE);
5343
5344 if (isdir(crlfile)) {
5345 ret = KMF_ERR_BAD_CRLFILE;
5346 goto end;
5347 }
5348
5349 ret = kmf_is_crl_file(handle, crlfile, &format);
5350 if (ret != KMF_OK)
5351 goto end;
5352
5353 /* Read the CRL file and load it into a X509_CRL structure */
5354 in = BIO_new_file(crlfilename, "rb");
5355 if (in == NULL) {
5356 SET_ERROR(kmfh, ERR_get_error());
5357 ret = KMF_ERR_OPEN_FILE;
5358 goto end;
5359 }
5360
5361 if (format == KMF_FORMAT_ASN1) {
5362 xcrl = d2i_X509_CRL_bio(in, NULL);
5363 } else if (format == KMF_FORMAT_PEM) {
5364 xcrl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
5365 }
5366
5367 if (xcrl == NULL) {
5368 SET_ERROR(kmfh, ERR_get_error());
5369 ret = KMF_ERR_BAD_CRLFILE;
5370 goto end;
5371 }
5372 (void) BIO_free(in);
5373
5374 /* Read the Certificate file and load it into a X509 structure */
5375 ret = kmf_is_cert_file(handle, certfile, &format);
5376 if (ret != KMF_OK)
5377 goto end;
5378
5379 in = BIO_new_file(certfile, "rb");
5380 if (in == NULL) {
5381 SET_ERROR(kmfh, ERR_get_error());
5382 ret = KMF_ERR_OPEN_FILE;
5383 goto end;
5384 }
5385
5386 if (format == KMF_FORMAT_ASN1) {
5387 xcert = d2i_X509_bio(in, NULL);
5388 } else if (format == KMF_FORMAT_PEM) {
5389 xcert = PEM_read_bio_X509(in, NULL, NULL, NULL);
5390 }
5391
5392 if (xcert == NULL) {
5393 SET_ERROR(kmfh, ERR_get_error());
5394 ret = KMF_ERR_BAD_CERTFILE;
5395 goto end;
5396 }
5397
5398 /* Check if the certificate and the CRL have same issuer */
5399 if (X509_NAME_cmp(xcert->cert_info->issuer, xcrl->crl->issuer) != 0) {
5400 ret = KMF_ERR_ISSUER;
5401 goto end;
5402 }
5403
5404 /* Check to see if the certificate serial number is revoked */
5405 revoke_stack = X509_CRL_get_REVOKED(xcrl);
5406 if (sk_X509_REVOKED_num(revoke_stack) <= 0) {
5407 /* No revoked certificates in the CRL file */
5408 SET_ERROR(kmfh, ERR_get_error());
5409 ret = KMF_ERR_EMPTY_CRL;
5410 goto end;
5411 }
5412
5413 for (i = 0; i < sk_X509_REVOKED_num(revoke_stack); i++) {
5414 revoke = sk_X509_REVOKED_value(revoke_stack, i);
5415 if (ASN1_INTEGER_cmp(xcert->cert_info->serialNumber,
5416 revoke->serialNumber) == 0) {
5417 break;
5418 }
5419 }
5420
5421 if (i < sk_X509_REVOKED_num(revoke_stack)) {
5422 ret = KMF_OK;
5423 } else {
5424 ret = KMF_ERR_NOT_REVOKED;
5425 }
5426
5427 end:
5428 if (in != NULL)
5429 (void) BIO_free(in);
5430 if (xcrl != NULL)
5431 X509_CRL_free(xcrl);
5432 if (xcert != NULL)
5433 X509_free(xcert);
5434
5435 return (ret);
5436 }
5437
5438 KMF_RETURN
5439 OpenSSL_VerifyCRLFile(KMF_HANDLE_T handle, char *crlname, KMF_DATA *tacert)
5440 {
5441 KMF_RETURN ret = KMF_OK;
5442 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
5443 BIO *bcrl = NULL;
5444 X509_CRL *xcrl = NULL;
5445 X509 *xcert = NULL;
5446 EVP_PKEY *pkey;
5447 int sslret;
5448 KMF_ENCODE_FORMAT crl_format;
5449 unsigned char *p;
5450 long len;
5451
5452 if (handle == NULL || crlname == NULL || tacert == NULL) {
5453 return (KMF_ERR_BAD_PARAMETER);
5454 }
5455
5456 ret = kmf_get_file_format(crlname, &crl_format);
5457 if (ret != KMF_OK)
5458 return (ret);
5459
5460 bcrl = BIO_new_file(crlname, "rb");
5461 if (bcrl == NULL) {
5462 SET_ERROR(kmfh, ERR_get_error());
5463 ret = KMF_ERR_OPEN_FILE;
5464 goto cleanup;
5465 }
5466
5467 if (crl_format == KMF_FORMAT_ASN1) {
5468 xcrl = d2i_X509_CRL_bio(bcrl, NULL);
5469 } else if (crl_format == KMF_FORMAT_PEM) {
5470 xcrl = PEM_read_bio_X509_CRL(bcrl, NULL, NULL, NULL);
5471 } else {
5472 ret = KMF_ERR_BAD_PARAMETER;
5473 goto cleanup;
5474 }
5475
5476 if (xcrl == NULL) {
5477 SET_ERROR(kmfh, ERR_get_error());
5478 ret = KMF_ERR_BAD_CRLFILE;
5479 goto cleanup;
5480 }
5481
5482 p = tacert->Data;
5483 len = tacert->Length;
5484 xcert = d2i_X509(NULL, (const uchar_t **)&p, len);
5485
5486 if (xcert == NULL) {
5487 SET_ERROR(kmfh, ERR_get_error());
5488 ret = KMF_ERR_BAD_CERTFILE;
5489 goto cleanup;
5490 }
5491
5492 /* Get issuer certificate public key */
5493 pkey = X509_get_pubkey(xcert);
5494 if (pkey == NULL) {
5495 SET_ERROR(kmfh, ERR_get_error());
5496 ret = KMF_ERR_BAD_CERT_FORMAT;
5497 goto cleanup;
5498 }
5499
5500 /* Verify CRL signature */
5501 sslret = X509_CRL_verify(xcrl, pkey);
5502 EVP_PKEY_free(pkey);
5503 if (sslret > 0) {
5504 ret = KMF_OK;
5505 } else {
5506 SET_ERROR(kmfh, sslret);
5507 ret = KMF_ERR_BAD_CRLFILE;
5508 }
5509
5510 cleanup:
5511 if (bcrl != NULL)
5512 (void) BIO_free(bcrl);
5513
5514 if (xcrl != NULL)
5515 X509_CRL_free(xcrl);
5516
5517 if (xcert != NULL)
5518 X509_free(xcert);
5519
5520 return (ret);
5521
5522 }
5523
5524 KMF_RETURN
5525 OpenSSL_CheckCRLDate(KMF_HANDLE_T handle, char *crlname)
5526 {
5527 KMF_RETURN ret = KMF_OK;
5528 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
5529 KMF_ENCODE_FORMAT crl_format;
5530 BIO *bcrl = NULL;
5531 X509_CRL *xcrl = NULL;
5532 int i;
5533
5534 if (handle == NULL || crlname == NULL) {
5535 return (KMF_ERR_BAD_PARAMETER);
5536 }
5537
5538 ret = kmf_is_crl_file(handle, crlname, &crl_format);
5539 if (ret != KMF_OK)
5540 return (ret);
5541
5542 bcrl = BIO_new_file(crlname, "rb");
5543 if (bcrl == NULL) {
5544 SET_ERROR(kmfh, ERR_get_error());
5545 ret = KMF_ERR_OPEN_FILE;
5546 goto cleanup;
5547 }
5548
5549 if (crl_format == KMF_FORMAT_ASN1)
5550 xcrl = d2i_X509_CRL_bio(bcrl, NULL);
5551 else if (crl_format == KMF_FORMAT_PEM)
5552 xcrl = PEM_read_bio_X509_CRL(bcrl, NULL, NULL, NULL);
5553
5554 if (xcrl == NULL) {
5555 SET_ERROR(kmfh, ERR_get_error());
5556 ret = KMF_ERR_BAD_CRLFILE;
5557 goto cleanup;
5558 }
5559 i = X509_cmp_time(X509_CRL_get_lastUpdate(xcrl), NULL);
5560 if (i >= 0) {
5561 ret = KMF_ERR_VALIDITY_PERIOD;
5562 goto cleanup;
5563 }
5564 if (X509_CRL_get_nextUpdate(xcrl)) {
5565 i = X509_cmp_time(X509_CRL_get_nextUpdate(xcrl), NULL);
5566
5567 if (i <= 0) {
5568 ret = KMF_ERR_VALIDITY_PERIOD;
5569 goto cleanup;
5570 }
5571 }
5572
5573 ret = KMF_OK;
5574
5575 cleanup:
5576 if (bcrl != NULL)
5577 (void) BIO_free(bcrl);
5578
5579 if (xcrl != NULL)
5580 X509_CRL_free(xcrl);
5581
5582 return (ret);
5583 }