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