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