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_MD2WithRSA)
1806 md = EVP_md2();
1807 else if (AlgId == KMF_ALGID_SHA1WithRSA)
1808 md = EVP_sha1();
1809 else if (AlgId == KMF_ALGID_SHA256WithRSA)
1810 md = EVP_sha256();
1811 else if (AlgId == KMF_ALGID_SHA384WithRSA)
1812 md = EVP_sha384();
1813 else if (AlgId == KMF_ALGID_SHA512WithRSA)
1814 md = EVP_sha512();
1815 else if (AlgId == KMF_ALGID_RSA)
1816 md = NULL;
1817 else
1818 return (KMF_ERR_BAD_ALGORITHM);
1819
1820 if ((md == NULL) && (AlgId == KMF_ALGID_RSA)) {
1821 RSA *rsa = EVP_PKEY_get1_RSA((EVP_PKEY *)pkey);
1822
1823 p = output->Data;
1824 if ((len = RSA_private_encrypt(tobesigned->Length,
1825 tobesigned->Data, p, rsa,
1826 RSA_PKCS1_PADDING)) <= 0) {
1827 SET_ERROR(kmfh, ERR_get_error());
1828 ret = KMF_ERR_INTERNAL;
1829 }
1830 output->Length = len;
1831 } else {
1832 (void) EVP_MD_CTX_init(&ctx);
1833 (void) EVP_SignInit_ex(&ctx, md, NULL);
1834 (void) EVP_SignUpdate(&ctx, tobesigned->Data,
1835 (uint32_t)tobesigned->Length);
1836 len = (uint32_t)output->Length;
1837 p = output->Data;
1838 if (!EVP_SignFinal(&ctx, p, (uint32_t *)&len, pkey)) {
1839 SET_ERROR(kmfh, ERR_get_error());
1840 len = 0;
1841 ret = KMF_ERR_INTERNAL;
1842 }
1843 output->Length = len;
1844 (void) EVP_MD_CTX_cleanup(&ctx);
1845 }
1846 } else if (key->keyalg == KMF_DSA) {
1847 DSA *dsa = EVP_PKEY_get1_DSA(key->keyp);
1848
1849 uchar_t hash[EVP_MAX_MD_SIZE];
1850 uint32_t hashlen;
1851 DSA_SIG *dsasig;
1852
1853 if (AlgId == KMF_ALGID_DSA ||
1854 AlgId == KMF_ALGID_SHA1WithDSA)
1855 md = EVP_sha1();
1856 else if (AlgId == KMF_ALGID_SHA256WithDSA)
1857 md = EVP_sha256();
1858 else /* Bad algorithm */
1859 return (KMF_ERR_BAD_ALGORITHM);
1860
1861 /*
1862 * OpenSSL EVP_Sign operation automatically converts to
1863 * ASN.1 output so we do the operations separately so we
1864 * are assured of NOT getting ASN.1 output returned.
1865 * KMF does not want ASN.1 encoded results because
1866 * not all mechanisms return ASN.1 encodings (PKCS#11
1867 * and NSS return raw signature data).
1868 */
1869 EVP_MD_CTX_init(&ctx);
1870 (void) EVP_DigestInit_ex(&ctx, md, NULL);
1871 (void) EVP_DigestUpdate(&ctx, tobesigned->Data,
1872 tobesigned->Length);
1873 (void) EVP_DigestFinal_ex(&ctx, hash, &hashlen);
1874
1875 /* Only sign first 20 bytes for SHA2 */
1876 if (AlgId == KMF_ALGID_SHA256WithDSA)
1877 hashlen = 20;
1878 dsasig = DSA_do_sign(hash, hashlen, dsa);
1879 if (dsasig != NULL) {
1880 int i;
1881 output->Length = i = fixbnlen(dsasig->r, output->Data,
1882 hashlen);
1883
1884 output->Length += fixbnlen(dsasig->s, &output->Data[i],
1885 hashlen);
1886
1887 DSA_SIG_free(dsasig);
1888 } else {
1889 SET_ERROR(kmfh, ERR_get_error());
1890 }
1891 (void) EVP_MD_CTX_cleanup(&ctx);
1892 } else {
1893 return (KMF_ERR_BAD_PARAMETER);
1894 }
1895 cleanup:
1896 return (ret);
1897 }
1898
1899 KMF_RETURN
1900 /*ARGSUSED*/
OpenSSL_DeleteKey(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)1901 OpenSSL_DeleteKey(KMF_HANDLE_T handle,
1902 int numattr, KMF_ATTRIBUTE *attrlist)
1903 {
1904 KMF_RETURN rv = KMF_OK;
1905 KMF_KEY_HANDLE *key;
1906 boolean_t destroy = B_TRUE;
1907
1908 key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
1909 if (key == NULL || key->keyp == NULL)
1910 return (KMF_ERR_BAD_PARAMETER);
1911
1912 rv = kmf_get_attr(KMF_DESTROY_BOOL_ATTR, attrlist, numattr,
1913 (void *)&destroy, NULL);
1914 if (rv != KMF_OK) {
1915 /* "destroy" is optional. Default is TRUE */
1916 rv = KMF_OK;
1917 }
1918
1919 if (key->keyclass != KMF_ASYM_PUB &&
1920 key->keyclass != KMF_ASYM_PRI &&
1921 key->keyclass != KMF_SYMMETRIC)
1922 return (KMF_ERR_BAD_KEY_CLASS);
1923
1924 if (key->keyclass == KMF_SYMMETRIC) {
1925 kmf_free_raw_sym_key((KMF_RAW_SYM_KEY *)key->keyp);
1926 key->keyp = NULL;
1927 } else {
1928 if (key->keyp != NULL) {
1929 EVP_PKEY_free(key->keyp);
1930 key->keyp = NULL;
1931 }
1932 }
1933
1934 if (key->keylabel != NULL) {
1935 EVP_PKEY *pkey = NULL;
1936 /* If the file exists, make sure it is a proper key. */
1937 pkey = openssl_load_key(handle, key->keylabel);
1938 if (pkey == NULL) {
1939 if (key->keylabel != NULL) {
1940 free(key->keylabel);
1941 key->keylabel = NULL;
1942 }
1943 return (KMF_ERR_KEY_NOT_FOUND);
1944 }
1945 EVP_PKEY_free(pkey);
1946
1947 if (destroy) {
1948 if (unlink(key->keylabel) != 0) {
1949 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1950 SET_SYS_ERROR(kmfh, errno);
1951 rv = KMF_ERR_INTERNAL;
1952 }
1953 }
1954 if (key->keylabel != NULL) {
1955 free(key->keylabel);
1956 key->keylabel = NULL;
1957 }
1958 }
1959 return (rv);
1960 }
1961
1962 KMF_RETURN
OpenSSL_GetErrorString(KMF_HANDLE_T handle,char ** msgstr)1963 OpenSSL_GetErrorString(KMF_HANDLE_T handle, char **msgstr)
1964 {
1965 KMF_RETURN ret = KMF_OK;
1966 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1967 char str[256]; /* OpenSSL needs at least 120 byte buffer */
1968
1969 ERR_error_string_n(kmfh->lasterr.errcode, str, sizeof (str));
1970 if (strlen(str)) {
1971 *msgstr = (char *)strdup(str);
1972 if ((*msgstr) == NULL)
1973 ret = KMF_ERR_MEMORY;
1974 } else {
1975 *msgstr = NULL;
1976 }
1977
1978 return (ret);
1979 }
1980
1981 static int
ext2NID(int kmfext)1982 ext2NID(int kmfext)
1983 {
1984 switch (kmfext) {
1985 case KMF_X509_EXT_KEY_USAGE:
1986 return (NID_key_usage);
1987 case KMF_X509_EXT_PRIV_KEY_USAGE_PERIOD:
1988 return (NID_private_key_usage_period);
1989 case KMF_X509_EXT_CERT_POLICIES:
1990 return (NID_certificate_policies);
1991 case KMF_X509_EXT_SUBJ_ALTNAME:
1992 return (NID_subject_alt_name);
1993 case KMF_X509_EXT_ISSUER_ALTNAME:
1994 return (NID_issuer_alt_name);
1995 case KMF_X509_EXT_BASIC_CONSTRAINTS:
1996 return (NID_basic_constraints);
1997 case KMF_X509_EXT_EXT_KEY_USAGE:
1998 return (NID_ext_key_usage);
1999 case KMF_X509_EXT_AUTH_KEY_ID:
2000 return (NID_authority_key_identifier);
2001 case KMF_X509_EXT_CRL_DIST_POINTS:
2002 return (NID_crl_distribution_points);
2003 case KMF_X509_EXT_SUBJ_KEY_ID:
2004 return (NID_subject_key_identifier);
2005 case KMF_X509_EXT_POLICY_MAPPINGS:
2006 return (OBJ_sn2nid("policyMappings"));
2007 case KMF_X509_EXT_NAME_CONSTRAINTS:
2008 return (OBJ_sn2nid("nameConstraints"));
2009 case KMF_X509_EXT_POLICY_CONSTRAINTS:
2010 return (OBJ_sn2nid("policyConstraints"));
2011 case KMF_X509_EXT_INHIBIT_ANY_POLICY:
2012 return (OBJ_sn2nid("inhibitAnyPolicy"));
2013 case KMF_X509_EXT_FRESHEST_CRL:
2014 return (OBJ_sn2nid("freshestCRL"));
2015 default:
2016 return (NID_undef);
2017 }
2018 }
2019
2020 KMF_RETURN
OpenSSL_CertGetPrintable(KMF_HANDLE_T handle,const KMF_DATA * pcert,KMF_PRINTABLE_ITEM flag,char * resultStr)2021 OpenSSL_CertGetPrintable(KMF_HANDLE_T handle, const KMF_DATA *pcert,
2022 KMF_PRINTABLE_ITEM flag, char *resultStr)
2023 {
2024 KMF_RETURN ret = KMF_OK;
2025 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2026 X509 *xcert = NULL;
2027 unsigned char *outbuf = NULL;
2028 unsigned char *outbuf_p;
2029 char *tmpstr = NULL;
2030 int j;
2031 int ext_index, nid, len;
2032 BIO *mem = NULL;
2033 #if OPENSSL_VERSION_NUMBER < 0x10000000L
2034 STACK *emlst = NULL;
2035 #else
2036 STACK_OF(OPENSSL_STRING) *emlst = NULL;
2037 #endif
2038 X509_EXTENSION *ex;
2039 X509_CINF *ci;
2040
2041 if (pcert == NULL || pcert->Data == NULL || pcert->Length == 0) {
2042 return (KMF_ERR_BAD_PARAMETER);
2043 }
2044
2045 /* copy cert data to outbuf */
2046 outbuf = malloc(pcert->Length);
2047 if (outbuf == NULL) {
2048 return (KMF_ERR_MEMORY);
2049 }
2050 (void) memcpy(outbuf, pcert->Data, pcert->Length);
2051
2052 outbuf_p = outbuf; /* use a temp pointer; required by openssl */
2053 xcert = d2i_X509(NULL, (const uchar_t **)&outbuf_p, pcert->Length);
2054 if (xcert == NULL) {
2055 SET_ERROR(kmfh, ERR_get_error());
2056 ret = KMF_ERR_ENCODING;
2057 goto out;
2058 }
2059
2060 mem = BIO_new(BIO_s_mem());
2061 if (mem == NULL) {
2062 SET_ERROR(kmfh, ERR_get_error());
2063 ret = KMF_ERR_MEMORY;
2064 goto out;
2065 }
2066
2067 switch (flag) {
2068 case KMF_CERT_ISSUER:
2069 (void) X509_NAME_print_ex(mem, X509_get_issuer_name(xcert), 0,
2070 XN_FLAG_SEP_CPLUS_SPC);
2071 len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2072 break;
2073
2074 case KMF_CERT_SUBJECT:
2075 (void) X509_NAME_print_ex(mem, X509_get_subject_name(xcert), 0,
2076 XN_FLAG_SEP_CPLUS_SPC);
2077 len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2078 break;
2079
2080 case KMF_CERT_VERSION:
2081 tmpstr = i2s_ASN1_INTEGER(NULL, xcert->cert_info->version);
2082 (void) strncpy(resultStr, tmpstr, KMF_CERT_PRINTABLE_LEN);
2083 OPENSSL_free(tmpstr);
2084 len = strlen(resultStr);
2085 break;
2086
2087 case KMF_CERT_SERIALNUM:
2088 if (i2a_ASN1_INTEGER(mem, X509_get_serialNumber(xcert)) > 0) {
2089 (void) strcpy(resultStr, "0x");
2090 len = BIO_gets(mem, &resultStr[2],
2091 KMF_CERT_PRINTABLE_LEN - 2);
2092 }
2093 break;
2094
2095 case KMF_CERT_NOTBEFORE:
2096 (void) ASN1_TIME_print(mem, X509_get_notBefore(xcert));
2097 len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2098 break;
2099
2100 case KMF_CERT_NOTAFTER:
2101 (void) ASN1_TIME_print(mem, X509_get_notAfter(xcert));
2102 len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2103 break;
2104
2105 case KMF_CERT_PUBKEY_DATA:
2106 {
2107 EVP_PKEY *pkey = X509_get_pubkey(xcert);
2108 if (pkey == NULL) {
2109 SET_ERROR(kmfh, ERR_get_error());
2110 ret = KMF_ERR_ENCODING;
2111 goto out;
2112 }
2113
2114 if (pkey->type == EVP_PKEY_RSA) {
2115 (void) BIO_printf(mem,
2116 "RSA Public Key: (%d bit)\n",
2117 BN_num_bits(pkey->pkey.rsa->n));
2118 (void) RSA_print(mem, pkey->pkey.rsa, 0);
2119 } else if (pkey->type == EVP_PKEY_DSA) {
2120 (void) BIO_printf(mem,
2121 "%12sDSA Public Key:\n", "");
2122 (void) DSA_print(mem, pkey->pkey.dsa, 0);
2123 } else {
2124 (void) BIO_printf(mem,
2125 "%12sUnknown Public Key:\n", "");
2126 }
2127 (void) BIO_printf(mem, "\n");
2128 EVP_PKEY_free(pkey);
2129 }
2130 len = BIO_read(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2131 break;
2132 case KMF_CERT_SIGNATURE_ALG:
2133 case KMF_CERT_PUBKEY_ALG:
2134 if (flag == KMF_CERT_SIGNATURE_ALG) {
2135 len = i2a_ASN1_OBJECT(mem,
2136 xcert->sig_alg->algorithm);
2137 } else {
2138 len = i2a_ASN1_OBJECT(mem,
2139 xcert->cert_info->key->algor->algorithm);
2140 }
2141
2142 if (len > 0) {
2143 len = BIO_read(mem, resultStr,
2144 KMF_CERT_PRINTABLE_LEN);
2145 }
2146 break;
2147
2148 case KMF_CERT_EMAIL:
2149 emlst = X509_get1_email(xcert);
2150 #if OPENSSL_VERSION_NUMBER < 0x10000000L
2151 for (j = 0; j < sk_num(emlst); j++)
2152 (void) BIO_printf(mem, "%s\n", sk_value(emlst, j));
2153 #else
2154 for (j = 0; j < sk_OPENSSL_STRING_num(emlst); j++)
2155 (void) BIO_printf(mem, "%s\n",
2156 sk_OPENSSL_STRING_value(emlst, j));
2157 #endif
2158
2159 len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2160 X509_email_free(emlst);
2161 break;
2162 case KMF_X509_EXT_ISSUER_ALTNAME:
2163 case KMF_X509_EXT_SUBJ_ALTNAME:
2164 case KMF_X509_EXT_KEY_USAGE:
2165 case KMF_X509_EXT_PRIV_KEY_USAGE_PERIOD:
2166 case KMF_X509_EXT_CERT_POLICIES:
2167 case KMF_X509_EXT_BASIC_CONSTRAINTS:
2168 case KMF_X509_EXT_NAME_CONSTRAINTS:
2169 case KMF_X509_EXT_POLICY_CONSTRAINTS:
2170 case KMF_X509_EXT_EXT_KEY_USAGE:
2171 case KMF_X509_EXT_INHIBIT_ANY_POLICY:
2172 case KMF_X509_EXT_AUTH_KEY_ID:
2173 case KMF_X509_EXT_SUBJ_KEY_ID:
2174 case KMF_X509_EXT_POLICY_MAPPINGS:
2175 case KMF_X509_EXT_CRL_DIST_POINTS:
2176 case KMF_X509_EXT_FRESHEST_CRL:
2177 nid = ext2NID(flag);
2178 if (nid == NID_undef) {
2179 ret = KMF_ERR_EXTENSION_NOT_FOUND;
2180 goto out;
2181 }
2182 ci = xcert->cert_info;
2183
2184 ext_index = X509v3_get_ext_by_NID(ci->extensions, nid, -1);
2185 if (ext_index == -1) {
2186 SET_ERROR(kmfh, ERR_get_error());
2187
2188 ret = KMF_ERR_EXTENSION_NOT_FOUND;
2189 goto out;
2190 }
2191 ex = X509v3_get_ext(ci->extensions, ext_index);
2192
2193 (void) i2a_ASN1_OBJECT(mem, X509_EXTENSION_get_object(ex));
2194
2195 if (BIO_printf(mem, ": %s\n",
2196 X509_EXTENSION_get_critical(ex) ? "critical" : "") <= 0) {
2197 SET_ERROR(kmfh, ERR_get_error());
2198 ret = KMF_ERR_ENCODING;
2199 goto out;
2200 }
2201 if (!X509V3_EXT_print(mem, ex, X509V3_EXT_DUMP_UNKNOWN, 4)) {
2202 (void) BIO_printf(mem, "%*s", 4, "");
2203 (void) M_ASN1_OCTET_STRING_print(mem, ex->value);
2204 }
2205 if (BIO_write(mem, "\n", 1) <= 0) {
2206 SET_ERROR(kmfh, ERR_get_error());
2207 ret = KMF_ERR_ENCODING;
2208 goto out;
2209 }
2210 len = BIO_read(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2211 }
2212 if (len <= 0) {
2213 SET_ERROR(kmfh, ERR_get_error());
2214 ret = KMF_ERR_ENCODING;
2215 }
2216
2217 out:
2218 if (outbuf != NULL) {
2219 free(outbuf);
2220 }
2221
2222 if (xcert != NULL) {
2223 X509_free(xcert);
2224 }
2225
2226 if (mem != NULL) {
2227 (void) BIO_free(mem);
2228 }
2229
2230 return (ret);
2231 }
2232
2233 KMF_RETURN
2234 /*ARGSUSED*/
OpenSSL_FindPrikeyByCert(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)2235 OpenSSL_FindPrikeyByCert(KMF_HANDLE_T handle, int numattr,
2236 KMF_ATTRIBUTE *attrlist)
2237 {
2238 KMF_RETURN rv = KMF_OK;
2239 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
2240 KMF_KEY_CLASS keyclass = KMF_ASYM_PRI;
2241 KMF_KEY_HANDLE *key = NULL;
2242 uint32_t numkeys = 1; /* 1 key only */
2243 char *dirpath = NULL;
2244 char *keyfile = NULL;
2245 KMF_ATTRIBUTE new_attrlist[16];
2246 int i = 0;
2247
2248 /*
2249 * This is really just a FindKey operation, reuse the
2250 * FindKey function.
2251 */
2252 kmf_set_attr_at_index(new_attrlist, i,
2253 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
2254 i++;
2255
2256 kmf_set_attr_at_index(new_attrlist, i,
2257 KMF_COUNT_ATTR, &numkeys, sizeof (uint32_t));
2258 i++;
2259
2260 kmf_set_attr_at_index(new_attrlist, i,
2261 KMF_KEYCLASS_ATTR, &keyclass, sizeof (keyclass));
2262 i++;
2263
2264 key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
2265 if (key == NULL) {
2266 return (KMF_ERR_BAD_PARAMETER);
2267 } else {
2268 kmf_set_attr_at_index(new_attrlist, i,
2269 KMF_KEY_HANDLE_ATTR, key, sizeof (KMF_KEY_HANDLE));
2270 i++;
2271 }
2272
2273 dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
2274 if (dirpath != NULL) {
2275 kmf_set_attr_at_index(new_attrlist, i,
2276 KMF_DIRPATH_ATTR, dirpath, strlen(dirpath));
2277 i++;
2278 }
2279
2280 keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr);
2281 if (keyfile == NULL)
2282 return (KMF_ERR_BAD_PARAMETER);
2283 else {
2284 kmf_set_attr_at_index(new_attrlist, i,
2285 KMF_KEY_FILENAME_ATTR, keyfile, strlen(keyfile));
2286 i++;
2287 }
2288
2289 rv = OpenSSL_FindKey(handle, i, new_attrlist);
2290 return (rv);
2291 }
2292
2293 KMF_RETURN
2294 /*ARGSUSED*/
OpenSSL_DecryptData(KMF_HANDLE_T handle,KMF_KEY_HANDLE * key,KMF_OID * AlgOID,KMF_DATA * ciphertext,KMF_DATA * output)2295 OpenSSL_DecryptData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key,
2296 KMF_OID *AlgOID, KMF_DATA *ciphertext,
2297 KMF_DATA *output)
2298 {
2299 KMF_RETURN ret = KMF_OK;
2300 RSA *rsa = NULL;
2301 unsigned int in_len = 0, out_len = 0;
2302 unsigned int total_decrypted = 0, modulus_len = 0;
2303 uint8_t *in_data, *out_data;
2304 int i, blocks;
2305
2306 if (key == NULL || AlgOID == NULL ||
2307 ciphertext == NULL || output == NULL ||
2308 ciphertext->Data == NULL ||
2309 output->Data == NULL)
2310 return (KMF_ERR_BAD_PARAMETER);
2311
2312 if (key->keyalg == KMF_RSA) {
2313 rsa = EVP_PKEY_get1_RSA((EVP_PKEY *)key->keyp);
2314 modulus_len = RSA_size(rsa);
2315 } else {
2316 return (KMF_ERR_BAD_PARAMETER);
2317 }
2318
2319 blocks = ciphertext->Length/modulus_len;
2320 out_data = output->Data;
2321 in_data = ciphertext->Data;
2322 out_len = modulus_len - 11;
2323 in_len = modulus_len;
2324
2325 for (i = 0; i < blocks; i++) {
2326 out_len = RSA_private_decrypt(in_len,
2327 in_data, out_data, rsa, RSA_PKCS1_PADDING);
2328
2329 if (out_len == 0) {
2330 ret = KMF_ERR_INTERNAL;
2331 goto cleanup;
2332 }
2333
2334 out_data += out_len;
2335 total_decrypted += out_len;
2336 in_data += in_len;
2337 }
2338
2339 output->Length = total_decrypted;
2340
2341 cleanup:
2342 RSA_free(rsa);
2343 if (ret != KMF_OK)
2344 output->Length = 0;
2345
2346 return (ret);
2347
2348 }
2349
2350 /*
2351 * This function will create a certid from issuer_cert and user_cert.
2352 * The caller should use OCSP_CERTID_free(OCSP_CERTID *) to deallocate
2353 * certid memory after use.
2354 */
2355 static KMF_RETURN
create_certid(KMF_HANDLE_T handle,const KMF_DATA * issuer_cert,const KMF_DATA * user_cert,OCSP_CERTID ** certid)2356 create_certid(KMF_HANDLE_T handle, const KMF_DATA *issuer_cert,
2357 const KMF_DATA *user_cert, OCSP_CERTID **certid)
2358 {
2359 KMF_RETURN ret = KMF_OK;
2360 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2361 X509 *issuer = NULL;
2362 X509 *cert = NULL;
2363 unsigned char *ptmp;
2364
2365 if (issuer_cert == NULL || user_cert == NULL) {
2366 return (KMF_ERR_BAD_PARAMETER);
2367 }
2368
2369 /* convert the DER-encoded issuer cert to an internal X509 */
2370 ptmp = issuer_cert->Data;
2371 issuer = d2i_X509(NULL, (const uchar_t **)&ptmp,
2372 issuer_cert->Length);
2373 if (issuer == NULL) {
2374 SET_ERROR(kmfh, ERR_get_error());
2375 ret = KMF_ERR_OCSP_BAD_ISSUER;
2376 goto end;
2377 }
2378
2379 /* convert the DER-encoded user cert to an internal X509 */
2380 ptmp = user_cert->Data;
2381 cert = d2i_X509(NULL, (const uchar_t **)&ptmp,
2382 user_cert->Length);
2383 if (cert == NULL) {
2384 SET_ERROR(kmfh, ERR_get_error());
2385
2386 ret = KMF_ERR_OCSP_BAD_CERT;
2387 goto end;
2388 }
2389
2390 /* create a CERTID */
2391 *certid = OCSP_cert_to_id(NULL, cert, issuer);
2392 if (*certid == NULL) {
2393 SET_ERROR(kmfh, ERR_get_error());
2394 ret = KMF_ERR_OCSP_CERTID;
2395 goto end;
2396 }
2397
2398 end:
2399 if (issuer != NULL) {
2400 X509_free(issuer);
2401 }
2402
2403 if (cert != NULL) {
2404 X509_free(cert);
2405 }
2406
2407 return (ret);
2408 }
2409
2410 KMF_RETURN
OpenSSL_CreateOCSPRequest(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)2411 OpenSSL_CreateOCSPRequest(KMF_HANDLE_T handle,
2412 int numattr, KMF_ATTRIBUTE *attrlist)
2413 {
2414 KMF_RETURN ret = KMF_OK;
2415 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2416 OCSP_CERTID *id = NULL;
2417 OCSP_REQUEST *req = NULL;
2418 BIO *derbio = NULL;
2419 char *reqfile;
2420 KMF_DATA *issuer_cert;
2421 KMF_DATA *user_cert;
2422
2423 user_cert = kmf_get_attr_ptr(KMF_USER_CERT_DATA_ATTR,
2424 attrlist, numattr);
2425 if (user_cert == NULL)
2426 return (KMF_ERR_BAD_PARAMETER);
2427
2428 issuer_cert = kmf_get_attr_ptr(KMF_ISSUER_CERT_DATA_ATTR,
2429 attrlist, numattr);
2430 if (issuer_cert == NULL)
2431 return (KMF_ERR_BAD_PARAMETER);
2432
2433 reqfile = kmf_get_attr_ptr(KMF_OCSP_REQUEST_FILENAME_ATTR,
2434 attrlist, numattr);
2435 if (reqfile == NULL)
2436 return (KMF_ERR_BAD_PARAMETER);
2437
2438 ret = create_certid(handle, issuer_cert, user_cert, &id);
2439 if (ret != KMF_OK) {
2440 return (ret);
2441 }
2442
2443 /* Create an OCSP request */
2444 req = OCSP_REQUEST_new();
2445 if (req == NULL) {
2446 SET_ERROR(kmfh, ERR_get_error());
2447 ret = KMF_ERR_OCSP_CREATE_REQUEST;
2448 goto end;
2449 }
2450
2451 if (!OCSP_request_add0_id(req, id)) {
2452 ret = KMF_ERR_OCSP_CREATE_REQUEST;
2453 goto end;
2454 }
2455
2456 /* Write the request to the output file with DER encoding */
2457 derbio = BIO_new_file(reqfile, "wb");
2458 if (!derbio) {
2459 SET_ERROR(kmfh, ERR_get_error());
2460 ret = KMF_ERR_OPEN_FILE;
2461 goto end;
2462 }
2463 if (i2d_OCSP_REQUEST_bio(derbio, req) <= 0) {
2464 ret = KMF_ERR_ENCODING;
2465 }
2466
2467 end:
2468 /*
2469 * We don't need to free "id" explicitely, because OCSP_REQUEST_free()
2470 * will also deallocate certid's space.
2471 */
2472 if (req != NULL) {
2473 OCSP_REQUEST_free(req);
2474 }
2475
2476 if (derbio != NULL) {
2477 (void) BIO_free(derbio);
2478 }
2479
2480 return (ret);
2481 }
2482
2483 /* ocsp_find_signer_sk() is copied from openssl source */
ocsp_find_signer_sk(STACK_OF (X509)* certs,OCSP_RESPID * id)2484 static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id)
2485 {
2486 int i;
2487 unsigned char tmphash[SHA_DIGEST_LENGTH], *keyhash;
2488
2489 /* Easy if lookup by name */
2490 if (id->type == V_OCSP_RESPID_NAME)
2491 return (X509_find_by_subject(certs, id->value.byName));
2492
2493 /* Lookup by key hash */
2494
2495 /* If key hash isn't SHA1 length then forget it */
2496 if (id->value.byKey->length != SHA_DIGEST_LENGTH)
2497 return (NULL);
2498
2499 keyhash = id->value.byKey->data;
2500 /* Calculate hash of each key and compare */
2501 for (i = 0; i < sk_X509_num(certs); i++) {
2502 /* LINTED E_BAD_PTR_CAST_ALIGN */
2503 X509 *x = sk_X509_value(certs, i);
2504 /* Use pubkey_digest to get the key ID value */
2505 (void) X509_pubkey_digest(x, EVP_sha1(), tmphash, NULL);
2506 if (!memcmp(keyhash, tmphash, SHA_DIGEST_LENGTH))
2507 return (x);
2508 }
2509 return (NULL);
2510 }
2511
2512 /* ocsp_find_signer() is copied from openssl source */
2513 /* ARGSUSED2 */
2514 static int
ocsp_find_signer(X509 ** psigner,OCSP_BASICRESP * bs,STACK_OF (X509)* certs,X509_STORE * st,unsigned long flags)2515 ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, STACK_OF(X509) *certs,
2516 X509_STORE *st, unsigned long flags)
2517 {
2518 X509 *signer;
2519 OCSP_RESPID *rid = bs->tbsResponseData->responderId;
2520 if ((signer = ocsp_find_signer_sk(certs, rid))) {
2521 *psigner = signer;
2522 return (2);
2523 }
2524 if (!(flags & OCSP_NOINTERN) &&
2525 (signer = ocsp_find_signer_sk(bs->certs, rid))) {
2526 *psigner = signer;
2527 return (1);
2528 }
2529 /* Maybe lookup from store if by subject name */
2530
2531 *psigner = NULL;
2532 return (0);
2533 }
2534
2535 /*
2536 * This function will verify the signature of a basic response, using
2537 * the public key from the OCSP responder certificate.
2538 */
2539 static KMF_RETURN
check_response_signature(KMF_HANDLE_T handle,OCSP_BASICRESP * bs,KMF_DATA * signer_cert,KMF_DATA * issuer_cert)2540 check_response_signature(KMF_HANDLE_T handle, OCSP_BASICRESP *bs,
2541 KMF_DATA *signer_cert, KMF_DATA *issuer_cert)
2542 {
2543 KMF_RETURN ret = KMF_OK;
2544 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2545 STACK_OF(X509) *cert_stack = NULL;
2546 X509 *signer = NULL;
2547 X509 *issuer = NULL;
2548 EVP_PKEY *skey = NULL;
2549 unsigned char *ptmp;
2550
2551
2552 if (bs == NULL || issuer_cert == NULL)
2553 return (KMF_ERR_BAD_PARAMETER);
2554
2555 /*
2556 * Find the certificate that signed the basic response.
2557 *
2558 * If signer_cert is not NULL, we will use that as the signer cert.
2559 * Otherwise, we will check if the issuer cert is actually the signer.
2560 * If we still do not find a signer, we will look for it from the
2561 * certificate list came with the response file.
2562 */
2563 if (signer_cert != NULL) {
2564 ptmp = signer_cert->Data;
2565 signer = d2i_X509(NULL, (const uchar_t **)&ptmp,
2566 signer_cert->Length);
2567 if (signer == NULL) {
2568 SET_ERROR(kmfh, ERR_get_error());
2569 ret = KMF_ERR_OCSP_BAD_SIGNER;
2570 goto end;
2571 }
2572 } else {
2573 /*
2574 * Convert the issuer cert into X509 and push it into a
2575 * stack to be used by ocsp_find_signer().
2576 */
2577 ptmp = issuer_cert->Data;
2578 issuer = d2i_X509(NULL, (const uchar_t **)&ptmp,
2579 issuer_cert->Length);
2580 if (issuer == NULL) {
2581 SET_ERROR(kmfh, ERR_get_error());
2582 ret = KMF_ERR_OCSP_BAD_ISSUER;
2583 goto end;
2584 }
2585
2586 if ((cert_stack = sk_X509_new_null()) == NULL) {
2587 ret = KMF_ERR_INTERNAL;
2588 goto end;
2589 }
2590
2591 if (sk_X509_push(cert_stack, issuer) == NULL) {
2592 ret = KMF_ERR_INTERNAL;
2593 goto end;
2594 }
2595
2596 ret = ocsp_find_signer(&signer, bs, cert_stack, NULL, 0);
2597 if (!ret) {
2598 /* can not find the signer */
2599 ret = KMF_ERR_OCSP_BAD_SIGNER;
2600 goto end;
2601 }
2602 }
2603
2604 /* Verify the signature of the response */
2605 skey = X509_get_pubkey(signer);
2606 if (skey == NULL) {
2607 ret = KMF_ERR_OCSP_BAD_SIGNER;
2608 goto end;
2609 }
2610
2611 ret = OCSP_BASICRESP_verify(bs, skey, 0);
2612 if (ret == 0) {
2613 ret = KMF_ERR_OCSP_RESPONSE_SIGNATURE;
2614 goto end;
2615 }
2616
2617 end:
2618 if (issuer != NULL) {
2619 X509_free(issuer);
2620 }
2621
2622 if (signer != NULL) {
2623 X509_free(signer);
2624 }
2625
2626 if (skey != NULL) {
2627 EVP_PKEY_free(skey);
2628 }
2629
2630 if (cert_stack != NULL) {
2631 sk_X509_free(cert_stack);
2632 }
2633
2634 return (ret);
2635 }
2636
2637
2638
2639 KMF_RETURN
OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)2640 OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T handle,
2641 int numattr, KMF_ATTRIBUTE *attrlist)
2642 {
2643 KMF_RETURN ret = KMF_OK;
2644 BIO *derbio = NULL;
2645 OCSP_RESPONSE *resp = NULL;
2646 OCSP_BASICRESP *bs = NULL;
2647 OCSP_CERTID *id = NULL;
2648 OCSP_SINGLERESP *single = NULL;
2649 ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd;
2650 int index, status, reason;
2651 KMF_DATA *issuer_cert;
2652 KMF_DATA *user_cert;
2653 KMF_DATA *signer_cert;
2654 KMF_DATA *response;
2655 int *response_reason, *response_status, *cert_status;
2656 boolean_t ignore_response_sign = B_FALSE; /* default is FALSE */
2657 uint32_t response_lifetime;
2658
2659 issuer_cert = kmf_get_attr_ptr(KMF_ISSUER_CERT_DATA_ATTR,
2660 attrlist, numattr);
2661 if (issuer_cert == NULL)
2662 return (KMF_ERR_BAD_PARAMETER);
2663
2664 user_cert = kmf_get_attr_ptr(KMF_USER_CERT_DATA_ATTR,
2665 attrlist, numattr);
2666 if (user_cert == NULL)
2667 return (KMF_ERR_BAD_PARAMETER);
2668
2669 response = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_DATA_ATTR,
2670 attrlist, numattr);
2671 if (response == NULL)
2672 return (KMF_ERR_BAD_PARAMETER);
2673
2674 response_status = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_STATUS_ATTR,
2675 attrlist, numattr);
2676 if (response_status == NULL)
2677 return (KMF_ERR_BAD_PARAMETER);
2678
2679 response_reason = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_REASON_ATTR,
2680 attrlist, numattr);
2681 if (response_reason == NULL)
2682 return (KMF_ERR_BAD_PARAMETER);
2683
2684 cert_status = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_CERT_STATUS_ATTR,
2685 attrlist, numattr);
2686 if (cert_status == NULL)
2687 return (KMF_ERR_BAD_PARAMETER);
2688
2689 /* Read in the response */
2690 derbio = BIO_new_mem_buf(response->Data, response->Length);
2691 if (!derbio) {
2692 ret = KMF_ERR_MEMORY;
2693 return (ret);
2694 }
2695
2696 resp = d2i_OCSP_RESPONSE_bio(derbio, NULL);
2697 if (resp == NULL) {
2698 ret = KMF_ERR_OCSP_MALFORMED_RESPONSE;
2699 goto end;
2700 }
2701
2702 /* Check the response status */
2703 status = OCSP_response_status(resp);
2704 *response_status = status;
2705 if (status != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
2706 ret = KMF_ERR_OCSP_RESPONSE_STATUS;
2707 goto end;
2708 }
2709
2710 #ifdef DEBUG
2711 printf("Successfully checked the response file status.\n");
2712 #endif /* DEBUG */
2713
2714 /* Extract basic response */
2715 bs = OCSP_response_get1_basic(resp);
2716 if (bs == NULL) {
2717 ret = KMF_ERR_OCSP_NO_BASIC_RESPONSE;
2718 goto end;
2719 }
2720
2721 #ifdef DEBUG
2722 printf("Successfully retrieved the basic response.\n");
2723 #endif /* DEBUG */
2724
2725 /* Check the basic response signature if required */
2726 ret = kmf_get_attr(KMF_IGNORE_RESPONSE_SIGN_ATTR, attrlist, numattr,
2727 (void *)&ignore_response_sign, NULL);
2728 if (ret != KMF_OK)
2729 ret = KMF_OK;
2730
2731 signer_cert = kmf_get_attr_ptr(KMF_SIGNER_CERT_DATA_ATTR,
2732 attrlist, numattr);
2733
2734 if (ignore_response_sign == B_FALSE) {
2735 ret = check_response_signature(handle, bs,
2736 signer_cert, issuer_cert);
2737 if (ret != KMF_OK)
2738 goto end;
2739 }
2740
2741 #ifdef DEBUG
2742 printf("Successfully verified the response signature.\n");
2743 #endif /* DEBUG */
2744
2745 /* Create a certid for the certificate in question */
2746 ret = create_certid(handle, issuer_cert, user_cert, &id);
2747 if (ret != KMF_OK) {
2748 ret = KMF_ERR_OCSP_CERTID;
2749 goto end;
2750 }
2751
2752 #ifdef DEBUG
2753 printf("successfully created a certid for the cert.\n");
2754 #endif /* DEBUG */
2755
2756 /* Find the index of the single response for the certid */
2757 index = OCSP_resp_find(bs, id, -1);
2758 if (index < 0) {
2759 /* cound not find this certificate in the response */
2760 ret = KMF_ERR_OCSP_UNKNOWN_CERT;
2761 goto end;
2762 }
2763
2764 #ifdef DEBUG
2765 printf("Successfully found the single response index for the cert.\n");
2766 #endif /* DEBUG */
2767
2768 /* Retrieve the single response and get the cert status */
2769 single = OCSP_resp_get0(bs, index);
2770 status = OCSP_single_get0_status(single, &reason, &rev, &thisupd,
2771 &nextupd);
2772 if (status == V_OCSP_CERTSTATUS_GOOD) {
2773 *cert_status = OCSP_GOOD;
2774 } else if (status == V_OCSP_CERTSTATUS_UNKNOWN) {
2775 *cert_status = OCSP_UNKNOWN;
2776 } else { /* revoked */
2777 *cert_status = OCSP_REVOKED;
2778 *response_reason = reason;
2779 }
2780 ret = KMF_OK;
2781
2782 /* resp. time is optional, so we don't care about the return code. */
2783 (void) kmf_get_attr(KMF_RESPONSE_LIFETIME_ATTR, attrlist, numattr,
2784 (void *)&response_lifetime, NULL);
2785
2786 if (!OCSP_check_validity(thisupd, nextupd, 300,
2787 response_lifetime)) {
2788 ret = KMF_ERR_OCSP_STATUS_TIME_INVALID;
2789 goto end;
2790 }
2791
2792 #ifdef DEBUG
2793 printf("Successfully verify the time.\n");
2794 #endif /* DEBUG */
2795
2796 end:
2797 if (derbio != NULL)
2798 (void) BIO_free(derbio);
2799
2800 if (resp != NULL)
2801 OCSP_RESPONSE_free(resp);
2802
2803 if (bs != NULL)
2804 OCSP_BASICRESP_free(bs);
2805
2806 if (id != NULL)
2807 OCSP_CERTID_free(id);
2808
2809 return (ret);
2810 }
2811
2812 static KMF_RETURN
fetch_key(KMF_HANDLE_T handle,char * path,KMF_KEY_CLASS keyclass,KMF_KEY_HANDLE * key)2813 fetch_key(KMF_HANDLE_T handle, char *path,
2814 KMF_KEY_CLASS keyclass, KMF_KEY_HANDLE *key)
2815 {
2816 KMF_RETURN rv = KMF_OK;
2817 EVP_PKEY *pkey = NULL;
2818 KMF_RAW_SYM_KEY *rkey = NULL;
2819
2820 if (keyclass == KMF_ASYM_PRI ||
2821 keyclass == KMF_ASYM_PUB) {
2822 pkey = openssl_load_key(handle, path);
2823 if (pkey == NULL) {
2824 return (KMF_ERR_KEY_NOT_FOUND);
2825 }
2826 if (key != NULL) {
2827 if (pkey->type == EVP_PKEY_RSA)
2828 key->keyalg = KMF_RSA;
2829 else if (pkey->type == EVP_PKEY_DSA)
2830 key->keyalg = KMF_DSA;
2831
2832 key->kstype = KMF_KEYSTORE_OPENSSL;
2833 key->keyclass = keyclass;
2834 key->keyp = (void *)pkey;
2835 key->israw = FALSE;
2836 if (path != NULL &&
2837 ((key->keylabel = strdup(path)) == NULL)) {
2838 EVP_PKEY_free(pkey);
2839 return (KMF_ERR_MEMORY);
2840 }
2841 } else {
2842 EVP_PKEY_free(pkey);
2843 pkey = NULL;
2844 }
2845 } else if (keyclass == KMF_SYMMETRIC) {
2846 KMF_ENCODE_FORMAT fmt;
2847 /*
2848 * If the file is a recognized format,
2849 * then it is NOT a symmetric key.
2850 */
2851 rv = kmf_get_file_format(path, &fmt);
2852 if (rv == KMF_OK || fmt != 0) {
2853 return (KMF_ERR_KEY_NOT_FOUND);
2854 } else if (rv == KMF_ERR_ENCODING) {
2855 /*
2856 * If we don't know the encoding,
2857 * it is probably a symmetric key.
2858 */
2859 rv = KMF_OK;
2860 } else if (rv == KMF_ERR_OPEN_FILE) {
2861 return (KMF_ERR_KEY_NOT_FOUND);
2862 }
2863
2864 if (key != NULL) {
2865 KMF_DATA keyvalue;
2866 rkey = malloc(sizeof (KMF_RAW_SYM_KEY));
2867 if (rkey == NULL) {
2868 rv = KMF_ERR_MEMORY;
2869 goto out;
2870 }
2871
2872 (void) memset(rkey, 0, sizeof (KMF_RAW_SYM_KEY));
2873 rv = kmf_read_input_file(handle, path, &keyvalue);
2874 if (rv != KMF_OK)
2875 goto out;
2876
2877 rkey->keydata.len = keyvalue.Length;
2878 rkey->keydata.val = keyvalue.Data;
2879
2880 key->kstype = KMF_KEYSTORE_OPENSSL;
2881 key->keyclass = keyclass;
2882 key->israw = TRUE;
2883 key->keyp = (void *)rkey;
2884 if (path != NULL &&
2885 ((key->keylabel = strdup(path)) == NULL)) {
2886 rv = KMF_ERR_MEMORY;
2887 }
2888 }
2889 }
2890 out:
2891 if (rv != KMF_OK) {
2892 if (rkey != NULL) {
2893 kmf_free_raw_sym_key(rkey);
2894 }
2895 if (pkey != NULL)
2896 EVP_PKEY_free(pkey);
2897
2898 if (key != NULL) {
2899 key->keyalg = KMF_KEYALG_NONE;
2900 key->keyclass = KMF_KEYCLASS_NONE;
2901 key->keyp = NULL;
2902 }
2903 }
2904
2905 return (rv);
2906 }
2907
2908 KMF_RETURN
OpenSSL_FindKey(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)2909 OpenSSL_FindKey(KMF_HANDLE_T handle,
2910 int numattr, KMF_ATTRIBUTE *attrlist)
2911 {
2912 KMF_RETURN rv = KMF_OK;
2913 char *fullpath = NULL;
2914 uint32_t maxkeys;
2915 KMF_KEY_HANDLE *key;
2916 uint32_t *numkeys;
2917 KMF_KEY_CLASS keyclass;
2918 KMF_RAW_KEY_DATA *rawkey;
2919 char *dirpath;
2920 char *keyfile;
2921
2922 if (handle == NULL)
2923 return (KMF_ERR_BAD_PARAMETER);
2924
2925 numkeys = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr);
2926 if (numkeys == NULL)
2927 return (KMF_ERR_BAD_PARAMETER);
2928
2929 rv = kmf_get_attr(KMF_KEYCLASS_ATTR, attrlist, numattr,
2930 (void *)&keyclass, NULL);
2931 if (rv != KMF_OK)
2932 return (KMF_ERR_BAD_PARAMETER);
2933
2934 if (keyclass != KMF_ASYM_PUB &&
2935 keyclass != KMF_ASYM_PRI &&
2936 keyclass != KMF_SYMMETRIC)
2937 return (KMF_ERR_BAD_KEY_CLASS);
2938
2939 dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
2940 keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr);
2941
2942 fullpath = get_fullpath(dirpath, keyfile);
2943
2944 if (fullpath == NULL)
2945 return (KMF_ERR_BAD_PARAMETER);
2946
2947 maxkeys = *numkeys;
2948 if (maxkeys == 0)
2949 maxkeys = 0xFFFFFFFF;
2950 *numkeys = 0;
2951
2952 key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
2953 /* it is okay to have "keys" contains NULL */
2954
2955 /*
2956 * The caller may want a list of the raw key data as well.
2957 * Useful for importing keys from a file into other keystores.
2958 */
2959 rawkey = kmf_get_attr_ptr(KMF_RAW_KEY_ATTR, attrlist, numattr);
2960
2961 if (isdir(fullpath)) {
2962 DIR *dirp;
2963 struct dirent *dp;
2964 int n = 0;
2965
2966 /* open all files in the directory and attempt to read them */
2967 if ((dirp = opendir(fullpath)) == NULL) {
2968 return (KMF_ERR_BAD_PARAMETER);
2969 }
2970 rewinddir(dirp);
2971 while ((dp = readdir(dirp)) != NULL && n < maxkeys) {
2972 if (strcmp(dp->d_name, ".") &&
2973 strcmp(dp->d_name, "..")) {
2974 char *fname;
2975
2976 fname = get_fullpath(fullpath,
2977 (char *)&dp->d_name);
2978
2979 rv = fetch_key(handle, fname,
2980 keyclass, key ? &key[n] : NULL);
2981
2982 if (rv == KMF_OK) {
2983 if (key != NULL && rawkey != NULL)
2984 rv = convertToRawKey(
2985 key[n].keyp, &rawkey[n]);
2986 n++;
2987 }
2988
2989 if (rv != KMF_OK || key == NULL)
2990 free(fname);
2991 }
2992 }
2993 (void) closedir(dirp);
2994 free(fullpath);
2995 (*numkeys) = n;
2996 } else {
2997 rv = fetch_key(handle, fullpath, keyclass, key);
2998 if (rv == KMF_OK)
2999 (*numkeys) = 1;
3000
3001 if (rv != KMF_OK || key == NULL)
3002 free(fullpath);
3003
3004 if (rv == KMF_OK && key != NULL && rawkey != NULL) {
3005 rv = convertToRawKey(key->keyp, rawkey);
3006 }
3007 }
3008
3009 if (rv == KMF_OK && (*numkeys) == 0)
3010 rv = KMF_ERR_KEY_NOT_FOUND;
3011 else if (rv == KMF_ERR_KEY_NOT_FOUND && (*numkeys) > 0)
3012 rv = KMF_OK;
3013
3014 return (rv);
3015 }
3016
3017 #define HANDLE_PK12_ERROR { \
3018 SET_ERROR(kmfh, ERR_get_error()); \
3019 rv = KMF_ERR_ENCODING; \
3020 goto out; \
3021 }
3022
3023 static int
add_alias_to_bag(PKCS12_SAFEBAG * bag,X509 * xcert)3024 add_alias_to_bag(PKCS12_SAFEBAG *bag, X509 *xcert)
3025 {
3026 if (xcert != NULL && xcert->aux != NULL &&
3027 xcert->aux->alias != NULL) {
3028 if (PKCS12_add_friendlyname_asc(bag,
3029 (const char *)xcert->aux->alias->data,
3030 xcert->aux->alias->length) == 0)
3031 return (0);
3032 }
3033 return (1);
3034 }
3035
3036 static PKCS7 *
add_cert_to_safe(X509 * sslcert,KMF_CREDENTIAL * cred,uchar_t * keyid,unsigned int keyidlen)3037 add_cert_to_safe(X509 *sslcert, KMF_CREDENTIAL *cred,
3038 uchar_t *keyid, unsigned int keyidlen)
3039 {
3040 PKCS12_SAFEBAG *bag = NULL;
3041 PKCS7 *cert_authsafe = NULL;
3042 STACK_OF(PKCS12_SAFEBAG) *bag_stack;
3043
3044 bag_stack = sk_PKCS12_SAFEBAG_new_null();
3045 if (bag_stack == NULL)
3046 return (NULL);
3047
3048 /* Convert cert from X509 struct to PKCS#12 bag */
3049 bag = PKCS12_x5092certbag(sslcert);
3050 if (bag == NULL) {
3051 goto out;
3052 }
3053
3054 /* Add the key id to the certificate bag. */
3055 if (keyidlen > 0 && !PKCS12_add_localkeyid(bag, keyid, keyidlen)) {
3056 goto out;
3057 }
3058
3059 if (!add_alias_to_bag(bag, sslcert))
3060 goto out;
3061
3062 /* Pile it on the bag_stack. */
3063 if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag)) {
3064 goto out;
3065 }
3066 /* Turn bag_stack of certs into encrypted authsafe. */
3067 cert_authsafe = PKCS12_pack_p7encdata(
3068 NID_pbe_WithSHA1And40BitRC2_CBC,
3069 cred->cred, cred->credlen, NULL, 0,
3070 PKCS12_DEFAULT_ITER, bag_stack);
3071
3072 out:
3073 if (bag_stack != NULL)
3074 sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free);
3075
3076 return (cert_authsafe);
3077 }
3078
3079 static PKCS7 *
add_key_to_safe(EVP_PKEY * pkey,KMF_CREDENTIAL * cred,uchar_t * keyid,unsigned int keyidlen,char * label,int label_len)3080 add_key_to_safe(EVP_PKEY *pkey, KMF_CREDENTIAL *cred,
3081 uchar_t *keyid, unsigned int keyidlen,
3082 char *label, int label_len)
3083 {
3084 PKCS8_PRIV_KEY_INFO *p8 = NULL;
3085 STACK_OF(PKCS12_SAFEBAG) *bag_stack = NULL;
3086 PKCS12_SAFEBAG *bag = NULL;
3087 PKCS7 *key_authsafe = NULL;
3088
3089 p8 = EVP_PKEY2PKCS8(pkey);
3090 if (p8 == NULL) {
3091 return (NULL);
3092 }
3093 /* Put the shrouded key into a PKCS#12 bag. */
3094 bag = PKCS12_MAKE_SHKEYBAG(
3095 NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
3096 cred->cred, cred->credlen,
3097 NULL, 0, PKCS12_DEFAULT_ITER, p8);
3098
3099 /* Clean up the PKCS#8 shrouded key, don't need it now. */
3100 PKCS8_PRIV_KEY_INFO_free(p8);
3101 p8 = NULL;
3102
3103 if (bag == NULL) {
3104 return (NULL);
3105 }
3106 if (keyidlen && !PKCS12_add_localkeyid(bag, keyid, keyidlen))
3107 goto out;
3108 if (label != NULL && !PKCS12_add_friendlyname(bag, label, label_len))
3109 goto out;
3110
3111 /* Start a PKCS#12 safebag container for the private key. */
3112 bag_stack = sk_PKCS12_SAFEBAG_new_null();
3113 if (bag_stack == NULL)
3114 goto out;
3115
3116 /* Pile on the private key on the bag_stack. */
3117 if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag))
3118 goto out;
3119
3120 key_authsafe = PKCS12_pack_p7data(bag_stack);
3121
3122 out:
3123 if (bag_stack != NULL)
3124 sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free);
3125 bag_stack = NULL;
3126 return (key_authsafe);
3127 }
3128
3129 static EVP_PKEY *
ImportRawRSAKey(KMF_RAW_RSA_KEY * key)3130 ImportRawRSAKey(KMF_RAW_RSA_KEY *key)
3131 {
3132 RSA *rsa = NULL;
3133 EVP_PKEY *newkey = NULL;
3134
3135 if ((rsa = RSA_new()) == NULL)
3136 return (NULL);
3137
3138 if ((rsa->n = BN_bin2bn(key->mod.val, key->mod.len, rsa->n)) == NULL)
3139 return (NULL);
3140
3141 if ((rsa->e = BN_bin2bn(key->pubexp.val, key->pubexp.len, rsa->e)) ==
3142 NULL)
3143 return (NULL);
3144
3145 if (key->priexp.val != NULL)
3146 if ((rsa->d = BN_bin2bn(key->priexp.val, key->priexp.len,
3147 rsa->d)) == NULL)
3148 return (NULL);
3149
3150 if (key->prime1.val != NULL)
3151 if ((rsa->p = BN_bin2bn(key->prime1.val, key->prime1.len,
3152 rsa->p)) == NULL)
3153 return (NULL);
3154
3155 if (key->prime2.val != NULL)
3156 if ((rsa->q = BN_bin2bn(key->prime2.val, key->prime2.len,
3157 rsa->q)) == NULL)
3158 return (NULL);
3159
3160 if (key->exp1.val != NULL)
3161 if ((rsa->dmp1 = BN_bin2bn(key->exp1.val, key->exp1.len,
3162 rsa->dmp1)) == NULL)
3163 return (NULL);
3164
3165 if (key->exp2.val != NULL)
3166 if ((rsa->dmq1 = BN_bin2bn(key->exp2.val, key->exp2.len,
3167 rsa->dmq1)) == NULL)
3168 return (NULL);
3169
3170 if (key->coef.val != NULL)
3171 if ((rsa->iqmp = BN_bin2bn(key->coef.val, key->coef.len,
3172 rsa->iqmp)) == NULL)
3173 return (NULL);
3174
3175 if ((newkey = EVP_PKEY_new()) == NULL)
3176 return (NULL);
3177
3178 (void) EVP_PKEY_set1_RSA(newkey, rsa);
3179
3180 /* The original key must be freed once here or it leaks memory */
3181 RSA_free(rsa);
3182
3183 return (newkey);
3184 }
3185
3186 static EVP_PKEY *
ImportRawDSAKey(KMF_RAW_DSA_KEY * key)3187 ImportRawDSAKey(KMF_RAW_DSA_KEY *key)
3188 {
3189 DSA *dsa = NULL;
3190 EVP_PKEY *newkey = NULL;
3191
3192 if ((dsa = DSA_new()) == NULL)
3193 return (NULL);
3194
3195 if ((dsa->p = BN_bin2bn(key->prime.val, key->prime.len,
3196 dsa->p)) == NULL)
3197 return (NULL);
3198
3199 if ((dsa->q = BN_bin2bn(key->subprime.val, key->subprime.len,
3200 dsa->q)) == NULL)
3201 return (NULL);
3202
3203 if ((dsa->g = BN_bin2bn(key->base.val, key->base.len,
3204 dsa->g)) == NULL)
3205 return (NULL);
3206
3207 if ((dsa->priv_key = BN_bin2bn(key->value.val, key->value.len,
3208 dsa->priv_key)) == NULL)
3209 return (NULL);
3210
3211 if (key->pubvalue.val != NULL) {
3212 if ((dsa->pub_key = BN_bin2bn(key->pubvalue.val,
3213 key->pubvalue.len, dsa->pub_key)) == NULL)
3214 return (NULL);
3215 }
3216
3217 if ((newkey = EVP_PKEY_new()) == NULL)
3218 return (NULL);
3219
3220 (void) EVP_PKEY_set1_DSA(newkey, dsa);
3221
3222 /* The original key must be freed once here or it leaks memory */
3223 DSA_free(dsa);
3224 return (newkey);
3225 }
3226
3227 static EVP_PKEY *
raw_key_to_pkey(KMF_KEY_HANDLE * key)3228 raw_key_to_pkey(KMF_KEY_HANDLE *key)
3229 {
3230 EVP_PKEY *pkey = NULL;
3231 KMF_RAW_KEY_DATA *rawkey;
3232 ASN1_TYPE *attr = NULL;
3233 KMF_RETURN ret;
3234
3235 if (key == NULL || !key->israw)
3236 return (NULL);
3237
3238 rawkey = (KMF_RAW_KEY_DATA *)key->keyp;
3239 if (rawkey->keytype == KMF_RSA) {
3240 pkey = ImportRawRSAKey(&rawkey->rawdata.rsa);
3241 } else if (rawkey->keytype == KMF_DSA) {
3242 pkey = ImportRawDSAKey(&rawkey->rawdata.dsa);
3243 } else if (rawkey->keytype == KMF_ECDSA) {
3244 /*
3245 * OpenSSL in Solaris does not support EC for
3246 * legal reasons
3247 */
3248 return (NULL);
3249 } else {
3250 /* wrong kind of key */
3251 return (NULL);
3252 }
3253
3254 if (rawkey->label != NULL) {
3255 if ((attr = ASN1_TYPE_new()) == NULL) {
3256 EVP_PKEY_free(pkey);
3257 return (NULL);
3258 }
3259 attr->value.bmpstring = ASN1_STRING_type_new(V_ASN1_BMPSTRING);
3260 (void) ASN1_STRING_set(attr->value.bmpstring, rawkey->label,
3261 strlen(rawkey->label));
3262 attr->type = V_ASN1_BMPSTRING;
3263 attr->value.ptr = (char *)attr->value.bmpstring;
3264 ret = set_pkey_attrib(pkey, attr, NID_friendlyName);
3265 if (ret != KMF_OK) {
3266 EVP_PKEY_free(pkey);
3267 ASN1_TYPE_free(attr);
3268 return (NULL);
3269 }
3270 }
3271 if (rawkey->id.Data != NULL) {
3272 if ((attr = ASN1_TYPE_new()) == NULL) {
3273 EVP_PKEY_free(pkey);
3274 return (NULL);
3275 }
3276 attr->value.octet_string =
3277 ASN1_STRING_type_new(V_ASN1_OCTET_STRING);
3278 attr->type = V_ASN1_OCTET_STRING;
3279 (void) ASN1_STRING_set(attr->value.octet_string,
3280 rawkey->id.Data, rawkey->id.Length);
3281 attr->value.ptr = (char *)attr->value.octet_string;
3282 ret = set_pkey_attrib(pkey, attr, NID_localKeyID);
3283 if (ret != KMF_OK) {
3284 EVP_PKEY_free(pkey);
3285 ASN1_TYPE_free(attr);
3286 return (NULL);
3287 }
3288 }
3289 return (pkey);
3290 }
3291
3292 /*
3293 * Search a list of private keys to find one that goes with the certificate.
3294 */
3295 static EVP_PKEY *
find_matching_key(X509 * xcert,int numkeys,KMF_KEY_HANDLE * keylist)3296 find_matching_key(X509 *xcert, int numkeys, KMF_KEY_HANDLE *keylist)
3297 {
3298 int i;
3299 EVP_PKEY *pkey = NULL;
3300
3301 if (numkeys == 0 || keylist == NULL || xcert == NULL)
3302 return (NULL);
3303 for (i = 0; i < numkeys; i++) {
3304 if (keylist[i].israw)
3305 pkey = raw_key_to_pkey(&keylist[i]);
3306 else
3307 pkey = (EVP_PKEY *)keylist[i].keyp;
3308 if (pkey != NULL) {
3309 if (X509_check_private_key(xcert, pkey)) {
3310 return (pkey);
3311 } else {
3312 EVP_PKEY_free(pkey);
3313 pkey = NULL;
3314 }
3315 }
3316 }
3317 return (pkey);
3318 }
3319
3320 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)3321 local_export_pk12(KMF_HANDLE_T handle,
3322 KMF_CREDENTIAL *cred,
3323 int numcerts, KMF_X509_DER_CERT *certlist,
3324 int numkeys, KMF_KEY_HANDLE *keylist,
3325 char *filename)
3326 {
3327 KMF_RETURN rv = KMF_OK;
3328 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
3329 BIO *bio = NULL;
3330 PKCS7 *cert_authsafe = NULL;
3331 PKCS7 *key_authsafe = NULL;
3332 STACK_OF(PKCS7) *authsafe_stack = NULL;
3333 PKCS12 *p12_elem = NULL;
3334 int i;
3335
3336 if (numcerts == 0 && numkeys == 0)
3337 return (KMF_ERR_BAD_PARAMETER);
3338
3339 /*
3340 * Open the output file.
3341 */
3342 if ((bio = BIO_new_file(filename, "wb")) == NULL) {
3343 SET_ERROR(kmfh, ERR_get_error());
3344 rv = KMF_ERR_OPEN_FILE;
3345 goto cleanup;
3346 }
3347
3348 /* Start a PKCS#7 stack. */
3349 authsafe_stack = sk_PKCS7_new_null();
3350 if (authsafe_stack == NULL) {
3351 rv = KMF_ERR_MEMORY;
3352 goto cleanup;
3353 }
3354 if (numcerts > 0) {
3355 for (i = 0; rv == KMF_OK && i < numcerts; i++) {
3356 const uchar_t *p = certlist[i].certificate.Data;
3357 long len = certlist[i].certificate.Length;
3358 X509 *xcert = NULL;
3359 EVP_PKEY *pkey = NULL;
3360 unsigned char keyid[EVP_MAX_MD_SIZE];
3361 unsigned int keyidlen = 0;
3362
3363 xcert = d2i_X509(NULL, &p, len);
3364 if (xcert == NULL) {
3365 SET_ERROR(kmfh, ERR_get_error());
3366 rv = KMF_ERR_ENCODING;
3367 }
3368 if (certlist[i].kmf_private.label != NULL) {
3369 /* Set alias attribute */
3370 (void) X509_alias_set1(xcert,
3371 (uchar_t *)certlist[i].kmf_private.label,
3372 strlen(certlist[i].kmf_private.label));
3373 }
3374 /* Check if there is a key corresponding to this cert */
3375 pkey = find_matching_key(xcert, numkeys, keylist);
3376
3377 /*
3378 * If key is found, get fingerprint and create a
3379 * safebag.
3380 */
3381 if (pkey != NULL) {
3382 (void) X509_digest(xcert, EVP_sha1(),
3383 keyid, &keyidlen);
3384 key_authsafe = add_key_to_safe(pkey, cred,
3385 keyid, keyidlen,
3386 certlist[i].kmf_private.label,
3387 (certlist[i].kmf_private.label ?
3388 strlen(certlist[i].kmf_private.label) : 0));
3389
3390 if (key_authsafe == NULL) {
3391 X509_free(xcert);
3392 EVP_PKEY_free(pkey);
3393 goto cleanup;
3394 }
3395 /* Put the key safe into the Auth Safe */
3396 if (!sk_PKCS7_push(authsafe_stack,
3397 key_authsafe)) {
3398 X509_free(xcert);
3399 EVP_PKEY_free(pkey);
3400 goto cleanup;
3401 }
3402 }
3403
3404 /* create a certificate safebag */
3405 cert_authsafe = add_cert_to_safe(xcert, cred, keyid,
3406 keyidlen);
3407 if (cert_authsafe == NULL) {
3408 X509_free(xcert);
3409 EVP_PKEY_free(pkey);
3410 goto cleanup;
3411 }
3412 if (!sk_PKCS7_push(authsafe_stack, cert_authsafe)) {
3413 X509_free(xcert);
3414 EVP_PKEY_free(pkey);
3415 goto cleanup;
3416 }
3417
3418 X509_free(xcert);
3419 if (pkey)
3420 EVP_PKEY_free(pkey);
3421 }
3422 } else if (numcerts == 0 && numkeys > 0) {
3423 /*
3424 * If only adding keys to the file.
3425 */
3426 for (i = 0; i < numkeys; i++) {
3427 EVP_PKEY *pkey = NULL;
3428
3429 if (keylist[i].israw)
3430 pkey = raw_key_to_pkey(&keylist[i]);
3431 else
3432 pkey = (EVP_PKEY *)keylist[i].keyp;
3433
3434 if (pkey == NULL)
3435 continue;
3436
3437 key_authsafe = add_key_to_safe(pkey, cred,
3438 NULL, 0, NULL, 0);
3439
3440 if (key_authsafe == NULL) {
3441 EVP_PKEY_free(pkey);
3442 goto cleanup;
3443 }
3444 if (!sk_PKCS7_push(authsafe_stack, key_authsafe)) {
3445 EVP_PKEY_free(pkey);
3446 goto cleanup;
3447 }
3448 }
3449 }
3450 p12_elem = PKCS12_init(NID_pkcs7_data);
3451 if (p12_elem == NULL) {
3452 goto cleanup;
3453 }
3454
3455 /* Put the PKCS#7 stack into the PKCS#12 element. */
3456 if (!PKCS12_pack_authsafes(p12_elem, authsafe_stack)) {
3457 goto cleanup;
3458 }
3459
3460 /* Set the integrity MAC on the PKCS#12 element. */
3461 if (!PKCS12_set_mac(p12_elem, cred->cred, cred->credlen,
3462 NULL, 0, PKCS12_DEFAULT_ITER, NULL)) {
3463 goto cleanup;
3464 }
3465
3466 /* Write the PKCS#12 element to the export file. */
3467 if (!i2d_PKCS12_bio(bio, p12_elem)) {
3468 goto cleanup;
3469 }
3470 PKCS12_free(p12_elem);
3471
3472 cleanup:
3473 /* Clear away the PKCS#7 stack, we're done with it. */
3474 if (authsafe_stack)
3475 sk_PKCS7_pop_free(authsafe_stack, PKCS7_free);
3476
3477 if (bio != NULL)
3478 (void) BIO_free_all(bio);
3479
3480 return (rv);
3481 }
3482
3483 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)3484 openssl_build_pk12(KMF_HANDLE_T handle, int numcerts,
3485 KMF_X509_DER_CERT *certlist, int numkeys, KMF_KEY_HANDLE *keylist,
3486 KMF_CREDENTIAL *p12cred, char *filename)
3487 {
3488 KMF_RETURN rv;
3489
3490 if (certlist == NULL && keylist == NULL)
3491 return (KMF_ERR_BAD_PARAMETER);
3492
3493 rv = local_export_pk12(handle, p12cred, numcerts, certlist,
3494 numkeys, keylist, filename);
3495
3496 return (rv);
3497 }
3498
3499 KMF_RETURN
OpenSSL_ExportPK12(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)3500 OpenSSL_ExportPK12(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
3501 {
3502 KMF_RETURN rv;
3503 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
3504 char *fullpath = NULL;
3505 char *dirpath = NULL;
3506 char *certfile = NULL;
3507 char *keyfile = NULL;
3508 char *filename = NULL;
3509 KMF_CREDENTIAL *p12cred = NULL;
3510 KMF_X509_DER_CERT certdata;
3511 KMF_KEY_HANDLE key;
3512 int gotkey = 0;
3513 int gotcert = 0;
3514
3515 if (handle == NULL)
3516 return (KMF_ERR_BAD_PARAMETER);
3517
3518 /*
3519 * First, find the certificate.
3520 */
3521 dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
3522 certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr);
3523 if (certfile != NULL) {
3524 fullpath = get_fullpath(dirpath, certfile);
3525 if (fullpath == NULL)
3526 return (KMF_ERR_BAD_PARAMETER);
3527
3528 if (isdir(fullpath)) {
3529 free(fullpath);
3530 return (KMF_ERR_AMBIGUOUS_PATHNAME);
3531 }
3532
3533 (void) memset(&certdata, 0, sizeof (certdata));
3534 rv = kmf_load_cert(kmfh, NULL, NULL, NULL, NULL,
3535 fullpath, &certdata.certificate);
3536 if (rv != KMF_OK)
3537 goto end;
3538
3539 gotcert++;
3540 certdata.kmf_private.keystore_type = KMF_KEYSTORE_OPENSSL;
3541 free(fullpath);
3542 }
3543
3544 /*
3545 * Now find the private key.
3546 */
3547 keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr);
3548 if (keyfile != NULL) {
3549 fullpath = get_fullpath(dirpath, keyfile);
3550 if (fullpath == NULL)
3551 return (KMF_ERR_BAD_PARAMETER);
3552
3553 if (isdir(fullpath)) {
3554 free(fullpath);
3555 return (KMF_ERR_AMBIGUOUS_PATHNAME);
3556 }
3557
3558 (void) memset(&key, 0, sizeof (KMF_KEY_HANDLE));
3559 rv = fetch_key(handle, fullpath, KMF_ASYM_PRI, &key);
3560 if (rv != KMF_OK)
3561 goto end;
3562 gotkey++;
3563 }
3564
3565 /*
3566 * Open the output file.
3567 */
3568 filename = kmf_get_attr_ptr(KMF_OUTPUT_FILENAME_ATTR, attrlist,
3569 numattr);
3570 if (filename == NULL) {
3571 rv = KMF_ERR_BAD_PARAMETER;
3572 goto end;
3573 }
3574
3575 /* Stick the key and the cert into a PKCS#12 file */
3576 p12cred = kmf_get_attr_ptr(KMF_PK12CRED_ATTR, attrlist, numattr);
3577 if (p12cred == NULL) {
3578 rv = KMF_ERR_BAD_PARAMETER;
3579 goto end;
3580 }
3581
3582 rv = local_export_pk12(handle, p12cred, 1, &certdata,
3583 1, &key, filename);
3584
3585 end:
3586 if (fullpath)
3587 free(fullpath);
3588
3589 if (gotcert)
3590 kmf_free_kmf_cert(handle, &certdata);
3591 if (gotkey)
3592 kmf_free_kmf_key(handle, &key);
3593 return (rv);
3594 }
3595
3596 /*
3597 * Helper function to extract keys and certificates from
3598 * a single PEM file. Typically the file should contain a
3599 * private key and an associated public key wrapped in an x509 cert.
3600 * However, the file may be just a list of X509 certs with no keys.
3601 */
3602 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)3603 extract_pem(KMF_HANDLE *kmfh,
3604 char *issuer, char *subject, KMF_BIGINT *serial,
3605 char *filename, CK_UTF8CHAR *pin,
3606 CK_ULONG pinlen, EVP_PKEY **priv_key, KMF_DATA **certs,
3607 int *numcerts)
3608 /* ARGSUSED6 */
3609 {
3610 KMF_RETURN rv = KMF_OK;
3611 FILE *fp;
3612 STACK_OF(X509_INFO) *x509_info_stack = NULL;
3613 int i, ncerts = 0, matchcerts = 0;
3614 EVP_PKEY *pkey = NULL;
3615 X509_INFO *info;
3616 X509 *x;
3617 X509_INFO **cert_infos = NULL;
3618 KMF_DATA *certlist = NULL;
3619
3620 if (priv_key)
3621 *priv_key = NULL;
3622 if (certs)
3623 *certs = NULL;
3624 fp = fopen(filename, "r");
3625 if (fp == NULL)
3626 return (KMF_ERR_OPEN_FILE);
3627
3628 x509_info_stack = PEM_X509_INFO_read(fp, NULL, NULL, pin);
3629 if (x509_info_stack == NULL) {
3630 (void) fclose(fp);
3631 return (KMF_ERR_ENCODING);
3632 }
3633 cert_infos = (X509_INFO **)malloc(sk_X509_INFO_num(x509_info_stack) *
3634 sizeof (X509_INFO *));
3635 if (cert_infos == NULL) {
3636 (void) fclose(fp);
3637 rv = KMF_ERR_MEMORY;
3638 goto err;
3639 }
3640
3641 for (i = 0; i < sk_X509_INFO_num(x509_info_stack); i++) {
3642 /* LINTED E_BAD_PTR_CAST_ALIGN */
3643 cert_infos[ncerts] = sk_X509_INFO_value(x509_info_stack, i);
3644 ncerts++;
3645 }
3646
3647 if (ncerts == 0) {
3648 (void) fclose(fp);
3649 rv = KMF_ERR_CERT_NOT_FOUND;
3650 goto err;
3651 }
3652
3653 if (priv_key != NULL) {
3654 rewind(fp);
3655 pkey = PEM_read_PrivateKey(fp, NULL, NULL, pin);
3656 }
3657 (void) fclose(fp);
3658
3659 x = cert_infos[ncerts - 1]->x509;
3660 /*
3661 * Make sure the private key matchs the last cert in the file.
3662 */
3663 if (pkey != NULL && !X509_check_private_key(x, pkey)) {
3664 EVP_PKEY_free(pkey);
3665 rv = KMF_ERR_KEY_MISMATCH;
3666 goto err;
3667 }
3668
3669 certlist = (KMF_DATA *)calloc(ncerts, sizeof (KMF_DATA));
3670 if (certlist == NULL) {
3671 if (pkey != NULL)
3672 EVP_PKEY_free(pkey);
3673 rv = KMF_ERR_MEMORY;
3674 goto err;
3675 }
3676
3677 /*
3678 * Convert all of the certs to DER format.
3679 */
3680 matchcerts = 0;
3681 for (i = 0; rv == KMF_OK && certs != NULL && i < ncerts; i++) {
3682 boolean_t match = FALSE;
3683 info = cert_infos[ncerts - 1 - i];
3684
3685 rv = check_cert(info->x509, issuer, subject, serial, &match);
3686 if (rv != KMF_OK || match != TRUE) {
3687 rv = KMF_OK;
3688 continue;
3689 }
3690
3691 rv = ssl_cert2KMFDATA(kmfh, info->x509,
3692 &certlist[matchcerts++]);
3693
3694 if (rv != KMF_OK) {
3695 int j;
3696 for (j = 0; j < matchcerts; j++)
3697 kmf_free_data(&certlist[j]);
3698 free(certlist);
3699 certlist = NULL;
3700 ncerts = matchcerts = 0;
3701 }
3702 }
3703
3704 if (numcerts != NULL)
3705 *numcerts = matchcerts;
3706
3707 if (certs != NULL)
3708 *certs = certlist;
3709 else if (certlist != NULL) {
3710 for (i = 0; i < ncerts; i++)
3711 kmf_free_data(&certlist[i]);
3712 free(certlist);
3713 certlist = NULL;
3714 }
3715
3716 if (priv_key == NULL && pkey != NULL)
3717 EVP_PKEY_free(pkey);
3718 else if (priv_key != NULL && pkey != NULL)
3719 *priv_key = pkey;
3720
3721 err:
3722 /* Cleanup the stack of X509 info records */
3723 for (i = 0; i < sk_X509_INFO_num(x509_info_stack); i++) {
3724 /* LINTED E_BAD_PTR_CAST_ALIGN */
3725 info = (X509_INFO *)sk_X509_INFO_value(x509_info_stack, i);
3726 X509_INFO_free(info);
3727 }
3728 if (x509_info_stack)
3729 sk_X509_INFO_free(x509_info_stack);
3730
3731 if (cert_infos != NULL)
3732 free(cert_infos);
3733
3734 return (rv);
3735 }
3736
3737 static KMF_RETURN
openssl_parse_bags(STACK_OF (PKCS12_SAFEBAG)* bags,char * pin,STACK_OF (EVP_PKEY)* keys,STACK_OF (X509)* certs)3738 openssl_parse_bags(STACK_OF(PKCS12_SAFEBAG) *bags, char *pin,
3739 STACK_OF(EVP_PKEY) *keys, STACK_OF(X509) *certs)
3740 {
3741 KMF_RETURN ret;
3742 int i;
3743
3744 for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) {
3745 /* LINTED E_BAD_PTR_CAST_ALIGN */
3746 PKCS12_SAFEBAG *bag = sk_PKCS12_SAFEBAG_value(bags, i);
3747 ret = openssl_parse_bag(bag, pin, (pin ? strlen(pin) : 0),
3748 keys, certs);
3749
3750 if (ret != KMF_OK)
3751 return (ret);
3752 }
3753
3754 return (ret);
3755 }
3756
3757 static KMF_RETURN
set_pkey_attrib(EVP_PKEY * pkey,ASN1_TYPE * attrib,int nid)3758 set_pkey_attrib(EVP_PKEY *pkey, ASN1_TYPE *attrib, int nid)
3759 {
3760 X509_ATTRIBUTE *attr = NULL;
3761
3762 if (pkey == NULL || attrib == NULL)
3763 return (KMF_ERR_BAD_PARAMETER);
3764
3765 if (pkey->attributes == NULL) {
3766 pkey->attributes = sk_X509_ATTRIBUTE_new_null();
3767 if (pkey->attributes == NULL)
3768 return (KMF_ERR_MEMORY);
3769 }
3770 attr = X509_ATTRIBUTE_create(nid, attrib->type, attrib->value.ptr);
3771 if (attr != NULL) {
3772 int i;
3773 X509_ATTRIBUTE *a;
3774 for (i = 0;
3775 i < sk_X509_ATTRIBUTE_num(pkey->attributes); i++) {
3776 /* LINTED E_BAD_PTR_CASE_ALIGN */
3777 a = sk_X509_ATTRIBUTE_value(pkey->attributes, i);
3778 if (OBJ_obj2nid(a->object) == nid) {
3779 X509_ATTRIBUTE_free(a);
3780 /* LINTED E_BAD_PTR_CAST_ALIGN */
3781 (void) sk_X509_ATTRIBUTE_set(pkey->attributes,
3782 i, attr);
3783 return (KMF_OK);
3784 }
3785 }
3786 if (sk_X509_ATTRIBUTE_push(pkey->attributes, attr) == NULL) {
3787 X509_ATTRIBUTE_free(attr);
3788 return (KMF_ERR_MEMORY);
3789 }
3790 } else {
3791 return (KMF_ERR_MEMORY);
3792 }
3793
3794 return (KMF_OK);
3795 }
3796
3797 static KMF_RETURN
openssl_parse_bag(PKCS12_SAFEBAG * bag,char * pass,int passlen,STACK_OF (EVP_PKEY)* keylist,STACK_OF (X509)* certlist)3798 openssl_parse_bag(PKCS12_SAFEBAG *bag, char *pass, int passlen,
3799 STACK_OF(EVP_PKEY) *keylist, STACK_OF(X509) *certlist)
3800 {
3801 KMF_RETURN ret = KMF_OK;
3802 PKCS8_PRIV_KEY_INFO *p8 = NULL;
3803 EVP_PKEY *pkey = NULL;
3804 X509 *xcert = NULL;
3805 ASN1_TYPE *keyid = NULL;
3806 ASN1_TYPE *fname = NULL;
3807 uchar_t *data = NULL;
3808
3809 keyid = PKCS12_get_attr(bag, NID_localKeyID);
3810 fname = PKCS12_get_attr(bag, NID_friendlyName);
3811
3812 switch (M_PKCS12_bag_type(bag)) {
3813 case NID_keyBag:
3814 if (keylist == NULL)
3815 goto end;
3816 pkey = EVP_PKCS82PKEY(bag->value.keybag);
3817 if (pkey == NULL)
3818 ret = KMF_ERR_PKCS12_FORMAT;
3819
3820 break;
3821 case NID_pkcs8ShroudedKeyBag:
3822 if (keylist == NULL)
3823 goto end;
3824 p8 = M_PKCS12_decrypt_skey(bag, pass, passlen);
3825 if (p8 == NULL)
3826 return (KMF_ERR_AUTH_FAILED);
3827 pkey = EVP_PKCS82PKEY(p8);
3828 PKCS8_PRIV_KEY_INFO_free(p8);
3829 if (pkey == NULL)
3830 ret = KMF_ERR_PKCS12_FORMAT;
3831 break;
3832 case NID_certBag:
3833 if (certlist == NULL)
3834 goto end;
3835 if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate)
3836 return (KMF_ERR_PKCS12_FORMAT);
3837 xcert = M_PKCS12_certbag2x509(bag);
3838 if (xcert == NULL) {
3839 ret = KMF_ERR_PKCS12_FORMAT;
3840 goto end;
3841 }
3842 if (keyid != NULL) {
3843 if (X509_keyid_set1(xcert,
3844 keyid->value.octet_string->data,
3845 keyid->value.octet_string->length) == 0) {
3846 ret = KMF_ERR_PKCS12_FORMAT;
3847 goto end;
3848 }
3849 }
3850 if (fname != NULL) {
3851 int len, r;
3852 len = ASN1_STRING_to_UTF8(&data,
3853 fname->value.asn1_string);
3854 if (len > 0 && data != NULL) {
3855 r = X509_alias_set1(xcert, data, len);
3856 if (r == NULL) {
3857 ret = KMF_ERR_PKCS12_FORMAT;
3858 goto end;
3859 }
3860 } else {
3861 ret = KMF_ERR_PKCS12_FORMAT;
3862 goto end;
3863 }
3864 }
3865 if (sk_X509_push(certlist, xcert) == 0)
3866 ret = KMF_ERR_MEMORY;
3867 else
3868 xcert = NULL;
3869 break;
3870 case NID_safeContentsBag:
3871 return (openssl_parse_bags(bag->value.safes, pass,
3872 keylist, certlist));
3873 default:
3874 ret = KMF_ERR_PKCS12_FORMAT;
3875 break;
3876 }
3877
3878 /*
3879 * Set the ID and/or FriendlyName attributes on the key.
3880 * If converting to PKCS11 objects, these can translate to CKA_ID
3881 * and CKA_LABEL values.
3882 */
3883 if (pkey != NULL && ret == KMF_OK) {
3884 ASN1_TYPE *attr = NULL;
3885 if (keyid != NULL && keyid->type == V_ASN1_OCTET_STRING) {
3886 if ((attr = ASN1_TYPE_new()) == NULL)
3887 return (KMF_ERR_MEMORY);
3888 attr->value.octet_string =
3889 ASN1_STRING_dup(keyid->value.octet_string);
3890 attr->type = V_ASN1_OCTET_STRING;
3891 attr->value.ptr = (char *)attr->value.octet_string;
3892 ret = set_pkey_attrib(pkey, attr, NID_localKeyID);
3893 OPENSSL_free(attr);
3894 }
3895
3896 if (ret == KMF_OK && fname != NULL &&
3897 fname->type == V_ASN1_BMPSTRING) {
3898 if ((attr = ASN1_TYPE_new()) == NULL)
3899 return (KMF_ERR_MEMORY);
3900 attr->value.bmpstring =
3901 ASN1_STRING_dup(fname->value.bmpstring);
3902 attr->type = V_ASN1_BMPSTRING;
3903 attr->value.ptr = (char *)attr->value.bmpstring;
3904 ret = set_pkey_attrib(pkey, attr, NID_friendlyName);
3905 OPENSSL_free(attr);
3906 }
3907
3908 if (ret == KMF_OK && keylist != NULL &&
3909 sk_EVP_PKEY_push(keylist, pkey) == 0)
3910 ret = KMF_ERR_MEMORY;
3911 }
3912 if (ret == KMF_OK && keylist != NULL)
3913 pkey = NULL;
3914 end:
3915 if (pkey != NULL)
3916 EVP_PKEY_free(pkey);
3917 if (xcert != NULL)
3918 X509_free(xcert);
3919 if (data != NULL)
3920 OPENSSL_free(data);
3921
3922 return (ret);
3923 }
3924
3925 static KMF_RETURN
openssl_pkcs12_parse(PKCS12 * p12,char * pin,STACK_OF (EVP_PKEY)* keys,STACK_OF (X509)* certs,STACK_OF (X509)* ca)3926 openssl_pkcs12_parse(PKCS12 *p12, char *pin,
3927 STACK_OF(EVP_PKEY) *keys,
3928 STACK_OF(X509) *certs,
3929 STACK_OF(X509) *ca)
3930 /* ARGSUSED3 */
3931 {
3932 KMF_RETURN ret = KMF_OK;
3933 STACK_OF(PKCS7) *asafes = NULL;
3934 STACK_OF(PKCS12_SAFEBAG) *bags = NULL;
3935 int i, bagnid;
3936 PKCS7 *p7;
3937
3938 if (p12 == NULL || (keys == NULL && certs == NULL))
3939 return (KMF_ERR_BAD_PARAMETER);
3940
3941 if (pin == NULL || *pin == NULL) {
3942 if (PKCS12_verify_mac(p12, NULL, 0)) {
3943 pin = NULL;
3944 } else if (PKCS12_verify_mac(p12, "", 0)) {
3945 pin = "";
3946 } else {
3947 return (KMF_ERR_AUTH_FAILED);
3948 }
3949 } else if (!PKCS12_verify_mac(p12, pin, -1)) {
3950 return (KMF_ERR_AUTH_FAILED);
3951 }
3952
3953 if ((asafes = PKCS12_unpack_authsafes(p12)) == NULL)
3954 return (KMF_ERR_PKCS12_FORMAT);
3955
3956 for (i = 0; ret == KMF_OK && i < sk_PKCS7_num(asafes); i++) {
3957 bags = NULL;
3958 /* LINTED E_BAD_PTR_CAST_ALIGN */
3959 p7 = sk_PKCS7_value(asafes, i);
3960 bagnid = OBJ_obj2nid(p7->type);
3961
3962 if (bagnid == NID_pkcs7_data) {
3963 bags = PKCS12_unpack_p7data(p7);
3964 } else if (bagnid == NID_pkcs7_encrypted) {
3965 bags = PKCS12_unpack_p7encdata(p7, pin,
3966 (pin ? strlen(pin) : 0));
3967 } else {
3968 continue;
3969 }
3970 if (bags == NULL) {
3971 ret = KMF_ERR_PKCS12_FORMAT;
3972 goto out;
3973 }
3974
3975 if (openssl_parse_bags(bags, pin, keys, certs) != KMF_OK)
3976 ret = KMF_ERR_PKCS12_FORMAT;
3977
3978 sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
3979 }
3980 out:
3981 if (asafes != NULL)
3982 sk_PKCS7_pop_free(asafes, PKCS7_free);
3983
3984 return (ret);
3985 }
3986
3987 /*
3988 * Helper function to decrypt and parse PKCS#12 import file.
3989 */
3990 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)3991 extract_pkcs12(BIO *fbio, CK_UTF8CHAR *pin, CK_ULONG pinlen,
3992 STACK_OF(EVP_PKEY) **priv_key, STACK_OF(X509) **certs,
3993 STACK_OF(X509) **ca)
3994 /* ARGSUSED2 */
3995 {
3996 PKCS12 *pk12, *pk12_tmp;
3997 STACK_OF(EVP_PKEY) *pkeylist = NULL;
3998 STACK_OF(X509) *xcertlist = NULL;
3999 STACK_OF(X509) *cacertlist = NULL;
4000
4001 if ((pk12 = PKCS12_new()) == NULL) {
4002 return (KMF_ERR_MEMORY);
4003 }
4004
4005 if ((pk12_tmp = d2i_PKCS12_bio(fbio, &pk12)) == NULL) {
4006 /* This is ok; it seems to mean there is no more to read. */
4007 if (ERR_GET_LIB(ERR_peek_error()) == ERR_LIB_ASN1 &&
4008 ERR_GET_REASON(ERR_peek_error()) == ASN1_R_HEADER_TOO_LONG)
4009 goto end_extract_pkcs12;
4010
4011 PKCS12_free(pk12);
4012 return (KMF_ERR_PKCS12_FORMAT);
4013 }
4014 pk12 = pk12_tmp;
4015
4016 xcertlist = sk_X509_new_null();
4017 if (xcertlist == NULL) {
4018 PKCS12_free(pk12);
4019 return (KMF_ERR_MEMORY);
4020 }
4021 pkeylist = sk_EVP_PKEY_new_null();
4022 if (pkeylist == NULL) {
4023 sk_X509_pop_free(xcertlist, X509_free);
4024 PKCS12_free(pk12);
4025 return (KMF_ERR_MEMORY);
4026 }
4027
4028 if (openssl_pkcs12_parse(pk12, (char *)pin, pkeylist, xcertlist,
4029 cacertlist) != KMF_OK) {
4030 sk_X509_pop_free(xcertlist, X509_free);
4031 sk_EVP_PKEY_pop_free(pkeylist, EVP_PKEY_free);
4032 PKCS12_free(pk12);
4033 return (KMF_ERR_PKCS12_FORMAT);
4034 }
4035
4036 if (priv_key && pkeylist)
4037 *priv_key = pkeylist;
4038 else if (pkeylist)
4039 sk_EVP_PKEY_pop_free(pkeylist, EVP_PKEY_free);
4040 if (certs && xcertlist)
4041 *certs = xcertlist;
4042 else if (xcertlist)
4043 sk_X509_pop_free(xcertlist, X509_free);
4044 if (ca && cacertlist)
4045 *ca = cacertlist;
4046 else if (cacertlist)
4047 sk_X509_pop_free(cacertlist, X509_free);
4048
4049 end_extract_pkcs12:
4050
4051 PKCS12_free(pk12);
4052 return (KMF_OK);
4053 }
4054
4055 static KMF_RETURN
sslBN2KMFBN(BIGNUM * from,KMF_BIGINT * to)4056 sslBN2KMFBN(BIGNUM *from, KMF_BIGINT *to)
4057 {
4058 KMF_RETURN rv = KMF_OK;
4059 uint32_t sz;
4060
4061 sz = BN_num_bytes(from);
4062 to->val = (uchar_t *)malloc(sz);
4063 if (to->val == NULL)
4064 return (KMF_ERR_MEMORY);
4065
4066 if ((to->len = BN_bn2bin(from, to->val)) != sz) {
4067 free(to->val);
4068 to->val = NULL;
4069 to->len = 0;
4070 rv = KMF_ERR_MEMORY;
4071 }
4072
4073 return (rv);
4074 }
4075
4076 static KMF_RETURN
exportRawRSAKey(RSA * rsa,KMF_RAW_KEY_DATA * key)4077 exportRawRSAKey(RSA *rsa, KMF_RAW_KEY_DATA *key)
4078 {
4079 KMF_RETURN rv;
4080 KMF_RAW_RSA_KEY *kmfkey = &key->rawdata.rsa;
4081
4082 (void) memset(kmfkey, 0, sizeof (KMF_RAW_RSA_KEY));
4083 if ((rv = sslBN2KMFBN(rsa->n, &kmfkey->mod)) != KMF_OK)
4084 goto cleanup;
4085
4086 if ((rv = sslBN2KMFBN(rsa->e, &kmfkey->pubexp)) != KMF_OK)
4087 goto cleanup;
4088
4089 if (rsa->d != NULL)
4090 if ((rv = sslBN2KMFBN(rsa->d, &kmfkey->priexp)) != KMF_OK)
4091 goto cleanup;
4092
4093 if (rsa->p != NULL)
4094 if ((rv = sslBN2KMFBN(rsa->p, &kmfkey->prime1)) != KMF_OK)
4095 goto cleanup;
4096
4097 if (rsa->q != NULL)
4098 if ((rv = sslBN2KMFBN(rsa->q, &kmfkey->prime2)) != KMF_OK)
4099 goto cleanup;
4100
4101 if (rsa->dmp1 != NULL)
4102 if ((rv = sslBN2KMFBN(rsa->dmp1, &kmfkey->exp1)) != KMF_OK)
4103 goto cleanup;
4104
4105 if (rsa->dmq1 != NULL)
4106 if ((rv = sslBN2KMFBN(rsa->dmq1, &kmfkey->exp2)) != KMF_OK)
4107 goto cleanup;
4108
4109 if (rsa->iqmp != NULL)
4110 if ((rv = sslBN2KMFBN(rsa->iqmp, &kmfkey->coef)) != KMF_OK)
4111 goto cleanup;
4112 cleanup:
4113 if (rv != KMF_OK)
4114 kmf_free_raw_key(key);
4115 else
4116 key->keytype = KMF_RSA;
4117
4118 /*
4119 * Free the reference to this key, SSL will not actually free
4120 * the memory until the refcount == 0, so this is safe.
4121 */
4122 RSA_free(rsa);
4123
4124 return (rv);
4125 }
4126
4127 static KMF_RETURN
exportRawDSAKey(DSA * dsa,KMF_RAW_KEY_DATA * key)4128 exportRawDSAKey(DSA *dsa, KMF_RAW_KEY_DATA *key)
4129 {
4130 KMF_RETURN rv;
4131 KMF_RAW_DSA_KEY *kmfkey = &key->rawdata.dsa;
4132
4133 (void) memset(kmfkey, 0, sizeof (KMF_RAW_DSA_KEY));
4134 if ((rv = sslBN2KMFBN(dsa->p, &kmfkey->prime)) != KMF_OK)
4135 goto cleanup;
4136
4137 if ((rv = sslBN2KMFBN(dsa->q, &kmfkey->subprime)) != KMF_OK)
4138 goto cleanup;
4139
4140 if ((rv = sslBN2KMFBN(dsa->g, &kmfkey->base)) != KMF_OK)
4141 goto cleanup;
4142
4143 if ((rv = sslBN2KMFBN(dsa->priv_key, &kmfkey->value)) != KMF_OK)
4144 goto cleanup;
4145
4146 cleanup:
4147 if (rv != KMF_OK)
4148 kmf_free_raw_key(key);
4149 else
4150 key->keytype = KMF_DSA;
4151
4152 /*
4153 * Free the reference to this key, SSL will not actually free
4154 * the memory until the refcount == 0, so this is safe.
4155 */
4156 DSA_free(dsa);
4157
4158 return (rv);
4159 }
4160
4161 static KMF_RETURN
add_cert_to_list(KMF_HANDLE * kmfh,X509 * sslcert,KMF_X509_DER_CERT ** certlist,int * ncerts)4162 add_cert_to_list(KMF_HANDLE *kmfh, X509 *sslcert,
4163 KMF_X509_DER_CERT **certlist, int *ncerts)
4164 {
4165 KMF_RETURN rv = KMF_OK;
4166 KMF_X509_DER_CERT *list = (*certlist);
4167 KMF_X509_DER_CERT cert;
4168 int n = (*ncerts);
4169
4170 if (list == NULL) {
4171 list = (KMF_X509_DER_CERT *)malloc(sizeof (KMF_X509_DER_CERT));
4172 } else {
4173 list = (KMF_X509_DER_CERT *)realloc(list,
4174 sizeof (KMF_X509_DER_CERT) * (n + 1));
4175 }
4176
4177 if (list == NULL)
4178 return (KMF_ERR_MEMORY);
4179
4180 (void) memset(&cert, 0, sizeof (cert));
4181 rv = ssl_cert2KMFDATA(kmfh, sslcert, &cert.certificate);
4182 if (rv == KMF_OK) {
4183 int len = 0;
4184 /* Get the alias name for the cert if there is one */
4185 char *a = (char *)X509_alias_get0(sslcert, &len);
4186 if (a != NULL)
4187 cert.kmf_private.label = strdup(a);
4188 cert.kmf_private.keystore_type = KMF_KEYSTORE_OPENSSL;
4189
4190 list[n] = cert;
4191 (*ncerts) = n + 1;
4192
4193 *certlist = list;
4194 } else {
4195 free(list);
4196 }
4197
4198 return (rv);
4199 }
4200
4201 static KMF_RETURN
add_key_to_list(KMF_RAW_KEY_DATA ** keylist,KMF_RAW_KEY_DATA * newkey,int * nkeys)4202 add_key_to_list(KMF_RAW_KEY_DATA **keylist,
4203 KMF_RAW_KEY_DATA *newkey, int *nkeys)
4204 {
4205 KMF_RAW_KEY_DATA *list = (*keylist);
4206 int n = (*nkeys);
4207
4208 if (list == NULL) {
4209 list = (KMF_RAW_KEY_DATA *)malloc(sizeof (KMF_RAW_KEY_DATA));
4210 } else {
4211 list = (KMF_RAW_KEY_DATA *)realloc(list,
4212 sizeof (KMF_RAW_KEY_DATA) * (n + 1));
4213 }
4214
4215 if (list == NULL)
4216 return (KMF_ERR_MEMORY);
4217
4218 list[n] = *newkey;
4219 (*nkeys) = n + 1;
4220
4221 *keylist = list;
4222
4223 return (KMF_OK);
4224 }
4225
4226 static X509_ATTRIBUTE *
find_attr(STACK_OF (X509_ATTRIBUTE)* attrs,int nid)4227 find_attr(STACK_OF(X509_ATTRIBUTE) *attrs, int nid)
4228 {
4229 X509_ATTRIBUTE *a;
4230 int i;
4231
4232 if (attrs == NULL)
4233 return (NULL);
4234
4235 for (i = 0; i < sk_X509_ATTRIBUTE_num(attrs); i++) {
4236 /* LINTED E_BAD_PTR_CAST_ALIGN */
4237 a = sk_X509_ATTRIBUTE_value(attrs, i);
4238 if (OBJ_obj2nid(a->object) == nid)
4239 return (a);
4240 }
4241 return (NULL);
4242 }
4243
4244 static KMF_RETURN
convertToRawKey(EVP_PKEY * pkey,KMF_RAW_KEY_DATA * key)4245 convertToRawKey(EVP_PKEY *pkey, KMF_RAW_KEY_DATA *key)
4246 {
4247 KMF_RETURN rv = KMF_OK;
4248 X509_ATTRIBUTE *attr;
4249
4250 if (pkey == NULL || key == NULL)
4251 return (KMF_ERR_BAD_PARAMETER);
4252 /* Convert SSL key to raw key */
4253 switch (pkey->type) {
4254 case EVP_PKEY_RSA:
4255 rv = exportRawRSAKey(EVP_PKEY_get1_RSA(pkey),
4256 key);
4257 if (rv != KMF_OK)
4258 return (rv);
4259 break;
4260 case EVP_PKEY_DSA:
4261 rv = exportRawDSAKey(EVP_PKEY_get1_DSA(pkey),
4262 key);
4263 if (rv != KMF_OK)
4264 return (rv);
4265 break;
4266 default:
4267 return (KMF_ERR_BAD_PARAMETER);
4268 }
4269 /*
4270 * If friendlyName, add it to record.
4271 */
4272 attr = find_attr(pkey->attributes, NID_friendlyName);
4273 if (attr != NULL) {
4274 ASN1_TYPE *ty = NULL;
4275 int numattr = sk_ASN1_TYPE_num(attr->value.set);
4276 if (attr->single == 0 && numattr > 0) {
4277 /* LINTED E_BAD_PTR_CAST_ALIGN */
4278 ty = sk_ASN1_TYPE_value(attr->value.set, 0);
4279 }
4280 if (ty != NULL) {
4281 #if OPENSSL_VERSION_NUMBER < 0x10000000L
4282 key->label = uni2asc(ty->value.bmpstring->data,
4283 ty->value.bmpstring->length);
4284 #else
4285 key->label = OPENSSL_uni2asc(ty->value.bmpstring->data,
4286 ty->value.bmpstring->length);
4287 #endif
4288 }
4289 } else {
4290 key->label = NULL;
4291 }
4292
4293 /*
4294 * If KeyID, add it to record as a KMF_DATA object.
4295 */
4296 attr = find_attr(pkey->attributes, NID_localKeyID);
4297 if (attr != NULL) {
4298 ASN1_TYPE *ty = NULL;
4299 int numattr = sk_ASN1_TYPE_num(attr->value.set);
4300 if (attr->single == 0 && numattr > 0) {
4301 /* LINTED E_BAD_PTR_CAST_ALIGN */
4302 ty = sk_ASN1_TYPE_value(attr->value.set, 0);
4303 }
4304 key->id.Data = (uchar_t *)malloc(
4305 ty->value.octet_string->length);
4306 if (key->id.Data == NULL)
4307 return (KMF_ERR_MEMORY);
4308 (void) memcpy(key->id.Data, ty->value.octet_string->data,
4309 ty->value.octet_string->length);
4310 key->id.Length = ty->value.octet_string->length;
4311 } else {
4312 (void) memset(&key->id, 0, sizeof (KMF_DATA));
4313 }
4314
4315 return (rv);
4316 }
4317
4318 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)4319 convertPK12Objects(
4320 KMF_HANDLE *kmfh,
4321 STACK_OF(EVP_PKEY) *sslkeys,
4322 STACK_OF(X509) *sslcert,
4323 STACK_OF(X509) *sslcacerts,
4324 KMF_RAW_KEY_DATA **keylist, int *nkeys,
4325 KMF_X509_DER_CERT **certlist, int *ncerts)
4326 {
4327 KMF_RETURN rv = KMF_OK;
4328 KMF_RAW_KEY_DATA key;
4329 int i;
4330
4331 for (i = 0; sslkeys != NULL && i < sk_EVP_PKEY_num(sslkeys); i++) {
4332 /* LINTED E_BAD_PTR_CAST_ALIGN */
4333 EVP_PKEY *pkey = sk_EVP_PKEY_value(sslkeys, i);
4334 rv = convertToRawKey(pkey, &key);
4335 if (rv == KMF_OK)
4336 rv = add_key_to_list(keylist, &key, nkeys);
4337
4338 if (rv != KMF_OK)
4339 return (rv);
4340 }
4341
4342 /* Now add the certificate to the certlist */
4343 for (i = 0; sslcert != NULL && i < sk_X509_num(sslcert); i++) {
4344 /* LINTED E_BAD_PTR_CAST_ALIGN */
4345 X509 *cert = sk_X509_value(sslcert, i);
4346 rv = add_cert_to_list(kmfh, cert, certlist, ncerts);
4347 if (rv != KMF_OK)
4348 return (rv);
4349 }
4350
4351 /* Also add any included CA certs to the list */
4352 for (i = 0; sslcacerts != NULL && i < sk_X509_num(sslcacerts); i++) {
4353 X509 *c;
4354 /*
4355 * sk_X509_value() is macro that embeds a cast to (X509 *).
4356 * Here it translates into ((X509 *)sk_value((ca), (i))).
4357 * Lint is complaining about the embedded casting, and
4358 * to fix it, you need to fix openssl header files.
4359 */
4360 /* LINTED E_BAD_PTR_CAST_ALIGN */
4361 c = sk_X509_value(sslcacerts, i);
4362
4363 /* Now add the ca cert to the certlist */
4364 rv = add_cert_to_list(kmfh, c, certlist, ncerts);
4365 if (rv != KMF_OK)
4366 return (rv);
4367 }
4368 return (rv);
4369 }
4370
4371 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)4372 openssl_import_objects(KMF_HANDLE *kmfh,
4373 char *filename, KMF_CREDENTIAL *cred,
4374 KMF_X509_DER_CERT **certlist, int *ncerts,
4375 KMF_RAW_KEY_DATA **keylist, int *nkeys)
4376 {
4377 KMF_RETURN rv = KMF_OK;
4378 KMF_ENCODE_FORMAT format;
4379 BIO *bio = NULL;
4380 STACK_OF(EVP_PKEY) *privkeys = NULL;
4381 STACK_OF(X509) *certs = NULL;
4382 STACK_OF(X509) *cacerts = NULL;
4383
4384 /*
4385 * auto-detect the file format, regardless of what
4386 * the 'format' parameters in the params say.
4387 */
4388 rv = kmf_get_file_format(filename, &format);
4389 if (rv != KMF_OK) {
4390 return (rv);
4391 }
4392
4393 /* This function only works for PEM or PKCS#12 files */
4394 if (format != KMF_FORMAT_PEM &&
4395 format != KMF_FORMAT_PEM_KEYPAIR &&
4396 format != KMF_FORMAT_PKCS12)
4397 return (KMF_ERR_ENCODING);
4398
4399 *certlist = NULL;
4400 *keylist = NULL;
4401 *ncerts = 0;
4402 *nkeys = 0;
4403
4404 if (format == KMF_FORMAT_PKCS12) {
4405 bio = BIO_new_file(filename, "rb");
4406 if (bio == NULL) {
4407 SET_ERROR(kmfh, ERR_get_error());
4408 rv = KMF_ERR_OPEN_FILE;
4409 goto end;
4410 }
4411
4412 rv = extract_pkcs12(bio, (uchar_t *)cred->cred,
4413 (uint32_t)cred->credlen, &privkeys, &certs, &cacerts);
4414
4415 if (rv == KMF_OK)
4416 /* Convert keys and certs to exportable format */
4417 rv = convertPK12Objects(kmfh, privkeys, certs, cacerts,
4418 keylist, nkeys, certlist, ncerts);
4419 } else {
4420 EVP_PKEY *pkey;
4421 KMF_DATA *certdata = NULL;
4422 KMF_X509_DER_CERT *kmfcerts = NULL;
4423 int i;
4424 rv = extract_pem(kmfh, NULL, NULL, NULL, filename,
4425 (uchar_t *)cred->cred, (uint32_t)cred->credlen,
4426 &pkey, &certdata, ncerts);
4427
4428 /* Reached end of import file? */
4429 if (rv == KMF_OK && pkey != NULL) {
4430 privkeys = sk_EVP_PKEY_new_null();
4431 if (privkeys == NULL) {
4432 rv = KMF_ERR_MEMORY;
4433 goto end;
4434 }
4435 (void) sk_EVP_PKEY_push(privkeys, pkey);
4436 /* convert the certificate list here */
4437 if (*ncerts > 0 && certlist != NULL) {
4438 kmfcerts = (KMF_X509_DER_CERT *)calloc(*ncerts,
4439 sizeof (KMF_X509_DER_CERT));
4440 if (kmfcerts == NULL) {
4441 rv = KMF_ERR_MEMORY;
4442 goto end;
4443 }
4444 for (i = 0; i < *ncerts; i++) {
4445 kmfcerts[i].certificate = certdata[i];
4446 kmfcerts[i].kmf_private.keystore_type =
4447 KMF_KEYSTORE_OPENSSL;
4448 }
4449 *certlist = kmfcerts;
4450 }
4451 /*
4452 * Convert keys to exportable format, the certs
4453 * are already OK.
4454 */
4455 rv = convertPK12Objects(kmfh, privkeys, NULL, NULL,
4456 keylist, nkeys, NULL, NULL);
4457 }
4458 }
4459 end:
4460 if (bio != NULL)
4461 (void) BIO_free(bio);
4462
4463 if (privkeys)
4464 sk_EVP_PKEY_pop_free(privkeys, EVP_PKEY_free);
4465 if (certs)
4466 sk_X509_pop_free(certs, X509_free);
4467 if (cacerts)
4468 sk_X509_pop_free(cacerts, X509_free);
4469
4470 return (rv);
4471 }
4472
4473 static KMF_RETURN
create_deskey(DES_cblock ** deskey)4474 create_deskey(DES_cblock **deskey)
4475 {
4476 DES_cblock *key;
4477
4478 key = (DES_cblock *) malloc(sizeof (DES_cblock));
4479 if (key == NULL) {
4480 return (KMF_ERR_MEMORY);
4481 }
4482
4483 if (DES_random_key(key) == 0) {
4484 free(key);
4485 return (KMF_ERR_KEYGEN_FAILED);
4486 }
4487
4488 *deskey = key;
4489 return (KMF_OK);
4490 }
4491
4492 #define KEYGEN_RETRY 3
4493 #define DES3_KEY_SIZE 24
4494
4495 static KMF_RETURN
create_des3key(unsigned char ** des3key)4496 create_des3key(unsigned char **des3key)
4497 {
4498 KMF_RETURN ret = KMF_OK;
4499 DES_cblock *deskey1 = NULL;
4500 DES_cblock *deskey2 = NULL;
4501 DES_cblock *deskey3 = NULL;
4502 unsigned char *newkey = NULL;
4503 int retry;
4504
4505 if ((newkey = malloc(DES3_KEY_SIZE)) == NULL) {
4506 return (KMF_ERR_MEMORY);
4507 }
4508
4509 /* create the 1st DES key */
4510 if ((ret = create_deskey(&deskey1)) != KMF_OK) {
4511 goto out;
4512 }
4513
4514 /*
4515 * Create the 2nd DES key and make sure its value is different
4516 * from the 1st DES key.
4517 */
4518 retry = 0;
4519 do {
4520 if (deskey2 != NULL) {
4521 free(deskey2);
4522 deskey2 = NULL;
4523 }
4524
4525 if ((ret = create_deskey(&deskey2)) != KMF_OK) {
4526 goto out;
4527 }
4528
4529 if (memcmp((const void *) deskey1, (const void *) deskey2, 8)
4530 == 0) {
4531 ret = KMF_ERR_KEYGEN_FAILED;
4532 retry++;
4533 }
4534 } while (ret == KMF_ERR_KEYGEN_FAILED && retry < KEYGEN_RETRY);
4535
4536 if (ret != KMF_OK) {
4537 goto out;
4538 }
4539
4540 /*
4541 * Create the 3rd DES key and make sure its value is different
4542 * from the 2nd DES key.
4543 */
4544 retry = 0;
4545 do {
4546 if (deskey3 != NULL) {
4547 free(deskey3);
4548 deskey3 = NULL;
4549 }
4550
4551 if ((ret = create_deskey(&deskey3)) != KMF_OK) {
4552 goto out;
4553 }
4554
4555 if (memcmp((const void *)deskey2, (const void *)deskey3, 8)
4556 == 0) {
4557 ret = KMF_ERR_KEYGEN_FAILED;
4558 retry++;
4559 }
4560 } while (ret == KMF_ERR_KEYGEN_FAILED && retry < KEYGEN_RETRY);
4561
4562 if (ret != KMF_OK) {
4563 goto out;
4564 }
4565
4566 /* Concatenate 3 DES keys into a DES3 key */
4567 (void) memcpy((void *)newkey, (const void *)deskey1, 8);
4568 (void) memcpy((void *)(newkey + 8), (const void *)deskey2, 8);
4569 (void) memcpy((void *)(newkey + 16), (const void *)deskey3, 8);
4570 *des3key = newkey;
4571
4572 out:
4573 if (deskey1 != NULL)
4574 free(deskey1);
4575
4576 if (deskey2 != NULL)
4577 free(deskey2);
4578
4579 if (deskey3 != NULL)
4580 free(deskey3);
4581
4582 if (ret != KMF_OK && newkey != NULL)
4583 free(newkey);
4584
4585 return (ret);
4586 }
4587
4588 KMF_RETURN
OpenSSL_CreateSymKey(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)4589 OpenSSL_CreateSymKey(KMF_HANDLE_T handle,
4590 int numattr, KMF_ATTRIBUTE *attrlist)
4591 {
4592 KMF_RETURN ret = KMF_OK;
4593 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
4594 char *fullpath = NULL;
4595 KMF_RAW_SYM_KEY *rkey = NULL;
4596 DES_cblock *deskey = NULL;
4597 unsigned char *des3key = NULL;
4598 unsigned char *random = NULL;
4599 int fd = -1;
4600 KMF_KEY_HANDLE *symkey;
4601 KMF_KEY_ALG keytype;
4602 uint32_t keylen;
4603 uint32_t keylen_size = sizeof (keylen);
4604 char *dirpath;
4605 char *keyfile;
4606
4607 if (kmfh == NULL)
4608 return (KMF_ERR_UNINITIALIZED);
4609
4610 symkey = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
4611 if (symkey == NULL)
4612 return (KMF_ERR_BAD_PARAMETER);
4613
4614 dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
4615
4616 keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr);
4617 if (keyfile == NULL)
4618 return (KMF_ERR_BAD_PARAMETER);
4619
4620 ret = kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr,
4621 (void *)&keytype, NULL);
4622 if (ret != KMF_OK)
4623 return (KMF_ERR_BAD_PARAMETER);
4624
4625 ret = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr,
4626 &keylen, &keylen_size);
4627 if (ret == KMF_ERR_ATTR_NOT_FOUND &&
4628 (keytype == KMF_DES || keytype == KMF_DES3))
4629 /* keylength is not required for DES and 3DES */
4630 ret = KMF_OK;
4631 if (ret != KMF_OK)
4632 return (KMF_ERR_BAD_PARAMETER);
4633
4634 fullpath = get_fullpath(dirpath, keyfile);
4635 if (fullpath == NULL)
4636 return (KMF_ERR_BAD_PARAMETER);
4637
4638 /* If the requested file exists, return an error */
4639 if (test_for_file(fullpath, 0400) == 1) {
4640 free(fullpath);
4641 return (KMF_ERR_DUPLICATE_KEYFILE);
4642 }
4643
4644 fd = open(fullpath, O_CREAT|O_TRUNC|O_RDWR, 0400);
4645 if (fd == -1) {
4646 ret = KMF_ERR_OPEN_FILE;
4647 goto out;
4648 }
4649
4650 rkey = malloc(sizeof (KMF_RAW_SYM_KEY));
4651 if (rkey == NULL) {
4652 ret = KMF_ERR_MEMORY;
4653 goto out;
4654 }
4655 (void) memset(rkey, 0, sizeof (KMF_RAW_SYM_KEY));
4656
4657 if (keytype == KMF_DES) {
4658 if ((ret = create_deskey(&deskey)) != KMF_OK) {
4659 goto out;
4660 }
4661 rkey->keydata.val = (uchar_t *)deskey;
4662 rkey->keydata.len = 8;
4663
4664 symkey->keyalg = KMF_DES;
4665
4666 } else if (keytype == KMF_DES3) {
4667 if ((ret = create_des3key(&des3key)) != KMF_OK) {
4668 goto out;
4669 }
4670 rkey->keydata.val = (uchar_t *)des3key;
4671 rkey->keydata.len = DES3_KEY_SIZE;
4672 symkey->keyalg = KMF_DES3;
4673
4674 } else if (keytype == KMF_AES || keytype == KMF_RC4 ||
4675 keytype == KMF_GENERIC_SECRET) {
4676 int bytes;
4677
4678 if (keylen % 8 != 0) {
4679 ret = KMF_ERR_BAD_KEY_SIZE;
4680 goto out;
4681 }
4682
4683 if (keytype == KMF_AES) {
4684 if (keylen != 128 &&
4685 keylen != 192 &&
4686 keylen != 256) {
4687 ret = KMF_ERR_BAD_KEY_SIZE;
4688 goto out;
4689 }
4690 }
4691
4692 bytes = keylen/8;
4693 random = malloc(bytes);
4694 if (random == NULL) {
4695 ret = KMF_ERR_MEMORY;
4696 goto out;
4697 }
4698 if (RAND_bytes(random, bytes) != 1) {
4699 ret = KMF_ERR_KEYGEN_FAILED;
4700 goto out;
4701 }
4702
4703 rkey->keydata.val = (uchar_t *)random;
4704 rkey->keydata.len = bytes;
4705 symkey->keyalg = keytype;
4706
4707 } else {
4708 ret = KMF_ERR_BAD_KEY_TYPE;
4709 goto out;
4710 }
4711
4712 (void) write(fd, (const void *) rkey->keydata.val, rkey->keydata.len);
4713
4714 symkey->kstype = KMF_KEYSTORE_OPENSSL;
4715 symkey->keyclass = KMF_SYMMETRIC;
4716 symkey->keylabel = (char *)fullpath;
4717 symkey->israw = TRUE;
4718 symkey->keyp = rkey;
4719
4720 out:
4721 if (fd != -1)
4722 (void) close(fd);
4723
4724 if (ret != KMF_OK && fullpath != NULL) {
4725 free(fullpath);
4726 }
4727 if (ret != KMF_OK) {
4728 kmf_free_raw_sym_key(rkey);
4729 symkey->keyp = NULL;
4730 symkey->keyalg = KMF_KEYALG_NONE;
4731 }
4732
4733 return (ret);
4734 }
4735
4736 /*
4737 * Check a file to see if it is a CRL file with PEM or DER format.
4738 * If success, return its format in the "pformat" argument.
4739 */
4740 KMF_RETURN
OpenSSL_IsCRLFile(KMF_HANDLE_T handle,char * filename,int * pformat)4741 OpenSSL_IsCRLFile(KMF_HANDLE_T handle, char *filename, int *pformat)
4742 {
4743 KMF_RETURN ret = KMF_OK;
4744 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
4745 BIO *bio = NULL;
4746 X509_CRL *xcrl = NULL;
4747
4748 if (filename == NULL) {
4749 return (KMF_ERR_BAD_PARAMETER);
4750 }
4751
4752 bio = BIO_new_file(filename, "rb");
4753 if (bio == NULL) {
4754 SET_ERROR(kmfh, ERR_get_error());
4755 ret = KMF_ERR_OPEN_FILE;
4756 goto out;
4757 }
4758
4759 if ((xcrl = PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL)) != NULL) {
4760 *pformat = KMF_FORMAT_PEM;
4761 goto out;
4762 }
4763 (void) BIO_free(bio);
4764
4765 /*
4766 * Now try to read it as raw DER data.
4767 */
4768 bio = BIO_new_file(filename, "rb");
4769 if (bio == NULL) {
4770 SET_ERROR(kmfh, ERR_get_error());
4771 ret = KMF_ERR_OPEN_FILE;
4772 goto out;
4773 }
4774
4775 if ((xcrl = d2i_X509_CRL_bio(bio, NULL)) != NULL) {
4776 *pformat = KMF_FORMAT_ASN1;
4777 } else {
4778 ret = KMF_ERR_BAD_CRLFILE;
4779 }
4780
4781 out:
4782 if (bio != NULL)
4783 (void) BIO_free(bio);
4784
4785 if (xcrl != NULL)
4786 X509_CRL_free(xcrl);
4787
4788 return (ret);
4789 }
4790
4791 KMF_RETURN
OpenSSL_GetSymKeyValue(KMF_HANDLE_T handle,KMF_KEY_HANDLE * symkey,KMF_RAW_SYM_KEY * rkey)4792 OpenSSL_GetSymKeyValue(KMF_HANDLE_T handle, KMF_KEY_HANDLE *symkey,
4793 KMF_RAW_SYM_KEY *rkey)
4794 {
4795 KMF_RETURN rv = KMF_OK;
4796 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
4797 KMF_DATA keyvalue;
4798
4799 if (kmfh == NULL)
4800 return (KMF_ERR_UNINITIALIZED);
4801
4802 if (symkey == NULL || rkey == NULL)
4803 return (KMF_ERR_BAD_PARAMETER);
4804 else if (symkey->keyclass != KMF_SYMMETRIC)
4805 return (KMF_ERR_BAD_KEY_CLASS);
4806
4807 if (symkey->israw) {
4808 KMF_RAW_SYM_KEY *rawkey = (KMF_RAW_SYM_KEY *)symkey->keyp;
4809
4810 if (rawkey == NULL ||
4811 rawkey->keydata.val == NULL ||
4812 rawkey->keydata.len == 0)
4813 return (KMF_ERR_BAD_KEYHANDLE);
4814
4815 rkey->keydata.len = rawkey->keydata.len;
4816 if ((rkey->keydata.val = malloc(rkey->keydata.len)) == NULL)
4817 return (KMF_ERR_MEMORY);
4818 (void) memcpy(rkey->keydata.val, rawkey->keydata.val,
4819 rkey->keydata.len);
4820 } else {
4821 rv = kmf_read_input_file(handle, symkey->keylabel, &keyvalue);
4822 if (rv != KMF_OK)
4823 return (rv);
4824 rkey->keydata.len = keyvalue.Length;
4825 rkey->keydata.val = keyvalue.Data;
4826 }
4827
4828 return (rv);
4829 }
4830
4831 /*
4832 * substitute for the unsafe access(2) function.
4833 * If the file in question already exists, return 1.
4834 * else 0. If an error occurs during testing (other
4835 * than EEXIST), return -1.
4836 */
4837 static int
test_for_file(char * filename,mode_t mode)4838 test_for_file(char *filename, mode_t mode)
4839 {
4840 int fd;
4841
4842 /*
4843 * Try to create the file with the EXCL flag.
4844 * The call should fail if the file exists.
4845 */
4846 fd = open(filename, O_WRONLY|O_CREAT|O_EXCL, mode);
4847 if (fd == -1 && errno == EEXIST)
4848 return (1);
4849 else if (fd == -1) /* some other error */
4850 return (-1);
4851
4852 /* The file did NOT exist. Delete the testcase. */
4853 (void) close(fd);
4854 (void) unlink(filename);
4855 return (0);
4856 }
4857
4858 KMF_RETURN
OpenSSL_StoreKey(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)4859 OpenSSL_StoreKey(KMF_HANDLE_T handle, int numattr,
4860 KMF_ATTRIBUTE *attrlist)
4861 {
4862 KMF_RETURN rv = KMF_OK;
4863 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
4864 KMF_KEY_HANDLE *pubkey = NULL, *prikey = NULL;
4865 KMF_RAW_KEY_DATA *rawkey;
4866 EVP_PKEY *pkey = NULL;
4867 KMF_ENCODE_FORMAT format = KMF_FORMAT_PEM;
4868 KMF_CREDENTIAL cred = { NULL, 0 };
4869 BIO *out = NULL;
4870 int keys = 0;
4871 char *fullpath = NULL;
4872 char *keyfile = NULL;
4873 char *dirpath = NULL;
4874
4875 pubkey = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attrlist, numattr);
4876 if (pubkey != NULL)
4877 keys++;
4878
4879 prikey = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attrlist, numattr);
4880 if (prikey != NULL)
4881 keys++;
4882
4883 rawkey = kmf_get_attr_ptr(KMF_RAW_KEY_ATTR, attrlist, numattr);
4884 if (rawkey != NULL)
4885 keys++;
4886
4887 /*
4888 * Exactly 1 type of key must be passed to this function.
4889 */
4890 if (keys != 1)
4891 return (KMF_ERR_BAD_PARAMETER);
4892
4893 keyfile = (char *)kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist,
4894 numattr);
4895 if (keyfile == NULL)
4896 return (KMF_ERR_BAD_PARAMETER);
4897
4898 dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
4899
4900 fullpath = get_fullpath(dirpath, keyfile);
4901
4902 /* Once we have the full path, we don't need the pieces */
4903 if (fullpath == NULL)
4904 return (KMF_ERR_BAD_PARAMETER);
4905
4906 /* If the requested file exists, return an error */
4907 if (test_for_file(fullpath, 0400) == 1) {
4908 free(fullpath);
4909 return (KMF_ERR_DUPLICATE_KEYFILE);
4910 }
4911
4912 rv = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr,
4913 &format, NULL);
4914 if (rv != KMF_OK)
4915 /* format is optional. */
4916 rv = KMF_OK;
4917
4918 /* CRED is not required for OpenSSL files */
4919 (void) kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr,
4920 &cred, NULL);
4921
4922 /* Store the private key to the keyfile */
4923 out = BIO_new_file(fullpath, "wb");
4924 if (out == NULL) {
4925 SET_ERROR(kmfh, ERR_get_error());
4926 rv = KMF_ERR_OPEN_FILE;
4927 goto end;
4928 }
4929
4930 if (prikey != NULL && prikey->keyp != NULL) {
4931 if (prikey->keyalg == KMF_RSA ||
4932 prikey->keyalg == KMF_DSA) {
4933 pkey = (EVP_PKEY *)prikey->keyp;
4934
4935 rv = ssl_write_key(kmfh, format,
4936 out, &cred, pkey, TRUE);
4937
4938 if (rv == KMF_OK && prikey->keylabel == NULL) {
4939 prikey->keylabel = strdup(fullpath);
4940 if (prikey->keylabel == NULL)
4941 rv = KMF_ERR_MEMORY;
4942 }
4943 }
4944 } else if (pubkey != NULL && pubkey->keyp != NULL) {
4945 if (pubkey->keyalg == KMF_RSA ||
4946 pubkey->keyalg == KMF_DSA) {
4947 pkey = (EVP_PKEY *)pubkey->keyp;
4948
4949 rv = ssl_write_key(kmfh, format,
4950 out, &cred, pkey, FALSE);
4951
4952 if (rv == KMF_OK && pubkey->keylabel == NULL) {
4953 pubkey->keylabel = strdup(fullpath);
4954 if (pubkey->keylabel == NULL)
4955 rv = KMF_ERR_MEMORY;
4956 }
4957 }
4958 } else if (rawkey != NULL) {
4959 if (rawkey->keytype == KMF_RSA) {
4960 pkey = ImportRawRSAKey(&rawkey->rawdata.rsa);
4961 } else if (rawkey->keytype == KMF_DSA) {
4962 pkey = ImportRawDSAKey(&rawkey->rawdata.dsa);
4963 } else {
4964 rv = KMF_ERR_BAD_PARAMETER;
4965 }
4966 if (pkey != NULL) {
4967 KMF_KEY_CLASS kclass = KMF_ASYM_PRI;
4968
4969 rv = kmf_get_attr(KMF_KEYCLASS_ATTR, attrlist, numattr,
4970 (void *)&kclass, NULL);
4971 if (rv != KMF_OK)
4972 rv = KMF_OK;
4973 rv = ssl_write_key(kmfh, format, out,
4974 &cred, pkey, (kclass == KMF_ASYM_PRI));
4975 EVP_PKEY_free(pkey);
4976 }
4977 }
4978
4979 end:
4980
4981 if (out)
4982 (void) BIO_free(out);
4983
4984
4985 if (rv == KMF_OK)
4986 (void) chmod(fullpath, 0400);
4987
4988 free(fullpath);
4989 return (rv);
4990 }
4991
4992 KMF_RETURN
OpenSSL_ImportCRL(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)4993 OpenSSL_ImportCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
4994 {
4995 KMF_RETURN ret = KMF_OK;
4996 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
4997 X509_CRL *xcrl = NULL;
4998 X509 *xcert = NULL;
4999 EVP_PKEY *pkey;
5000 KMF_ENCODE_FORMAT format;
5001 BIO *in = NULL, *out = NULL;
5002 int openssl_ret = 0;
5003 KMF_ENCODE_FORMAT outformat;
5004 boolean_t crlcheck = FALSE;
5005 char *certfile, *dirpath, *crlfile, *incrl, *outcrl, *outcrlfile;
5006
5007 if (numattr == 0 || attrlist == NULL) {
5008 return (KMF_ERR_BAD_PARAMETER);
5009 }
5010
5011 /* CRL check is optional */
5012 (void) kmf_get_attr(KMF_CRL_CHECK_ATTR, attrlist, numattr,
5013 &crlcheck, NULL);
5014
5015 certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr);
5016 if (crlcheck == B_TRUE && certfile == NULL) {
5017 return (KMF_ERR_BAD_CERTFILE);
5018 }
5019
5020 dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
5021 incrl = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR, attrlist, numattr);
5022 outcrl = kmf_get_attr_ptr(KMF_CRL_OUTFILE_ATTR, attrlist, numattr);
5023
5024 crlfile = get_fullpath(dirpath, incrl);
5025
5026 if (crlfile == NULL)
5027 return (KMF_ERR_BAD_CRLFILE);
5028
5029 outcrlfile = get_fullpath(dirpath, outcrl);
5030 if (outcrlfile == NULL)
5031 return (KMF_ERR_BAD_CRLFILE);
5032
5033 if (isdir(outcrlfile)) {
5034 free(outcrlfile);
5035 return (KMF_ERR_BAD_CRLFILE);
5036 }
5037
5038 ret = kmf_is_crl_file(handle, crlfile, &format);
5039 if (ret != KMF_OK) {
5040 free(outcrlfile);
5041 return (ret);
5042 }
5043
5044 in = BIO_new_file(crlfile, "rb");
5045 if (in == NULL) {
5046 SET_ERROR(kmfh, ERR_get_error());
5047 ret = KMF_ERR_OPEN_FILE;
5048 goto end;
5049 }
5050
5051 if (format == KMF_FORMAT_ASN1) {
5052 xcrl = d2i_X509_CRL_bio(in, NULL);
5053 } else if (format == KMF_FORMAT_PEM) {
5054 xcrl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
5055 }
5056
5057 if (xcrl == NULL) {
5058 SET_ERROR(kmfh, ERR_get_error());
5059 ret = KMF_ERR_BAD_CRLFILE;
5060 goto end;
5061 }
5062
5063 /* If bypasscheck is specified, no need to verify. */
5064 if (crlcheck == B_FALSE)
5065 goto output;
5066
5067 ret = kmf_is_cert_file(handle, certfile, &format);
5068 if (ret != KMF_OK)
5069 goto end;
5070
5071 /* Read in the CA cert file and convert to X509 */
5072 if (BIO_read_filename(in, certfile) <= 0) {
5073 SET_ERROR(kmfh, ERR_get_error());
5074 ret = KMF_ERR_OPEN_FILE;
5075 goto end;
5076 }
5077
5078 if (format == KMF_FORMAT_ASN1) {
5079 xcert = d2i_X509_bio(in, NULL);
5080 } else if (format == KMF_FORMAT_PEM) {
5081 xcert = PEM_read_bio_X509(in, NULL, NULL, NULL);
5082 } else {
5083 ret = KMF_ERR_BAD_CERT_FORMAT;
5084 goto end;
5085 }
5086
5087 if (xcert == NULL) {
5088 SET_ERROR(kmfh, ERR_get_error());
5089 ret = KMF_ERR_BAD_CERT_FORMAT;
5090 goto end;
5091 }
5092 /* Now get the public key from the CA cert */
5093 pkey = X509_get_pubkey(xcert);
5094 if (pkey == NULL) {
5095 SET_ERROR(kmfh, ERR_get_error());
5096 ret = KMF_ERR_BAD_CERTFILE;
5097 goto end;
5098 }
5099
5100 /* Verify the CRL with the CA's public key */
5101 openssl_ret = X509_CRL_verify(xcrl, pkey);
5102 EVP_PKEY_free(pkey);
5103 if (openssl_ret > 0) {
5104 ret = KMF_OK; /* verify succeed */
5105 } else {
5106 SET_ERROR(kmfh, openssl_ret);
5107 ret = KMF_ERR_BAD_CRLFILE;
5108 }
5109
5110 output:
5111 ret = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr,
5112 &outformat, NULL);
5113 if (ret != KMF_OK) {
5114 ret = KMF_OK;
5115 outformat = KMF_FORMAT_PEM;
5116 }
5117
5118 out = BIO_new_file(outcrlfile, "wb");
5119 if (out == NULL) {
5120 SET_ERROR(kmfh, ERR_get_error());
5121 ret = KMF_ERR_OPEN_FILE;
5122 goto end;
5123 }
5124
5125 if (outformat == KMF_FORMAT_ASN1) {
5126 openssl_ret = (int)i2d_X509_CRL_bio(out, xcrl);
5127 } else if (outformat == KMF_FORMAT_PEM) {
5128 openssl_ret = PEM_write_bio_X509_CRL(out, xcrl);
5129 } else {
5130 ret = KMF_ERR_BAD_PARAMETER;
5131 goto end;
5132 }
5133
5134 if (openssl_ret <= 0) {
5135 SET_ERROR(kmfh, ERR_get_error());
5136 ret = KMF_ERR_WRITE_FILE;
5137 } else {
5138 ret = KMF_OK;
5139 }
5140
5141 end:
5142 if (xcrl != NULL)
5143 X509_CRL_free(xcrl);
5144
5145 if (xcert != NULL)
5146 X509_free(xcert);
5147
5148 if (in != NULL)
5149 (void) BIO_free(in);
5150
5151 if (out != NULL)
5152 (void) BIO_free(out);
5153
5154 if (outcrlfile != NULL)
5155 free(outcrlfile);
5156
5157 return (ret);
5158 }
5159
5160 KMF_RETURN
OpenSSL_ListCRL(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)5161 OpenSSL_ListCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
5162 {
5163 KMF_RETURN ret = KMF_OK;
5164 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
5165 X509_CRL *x = NULL;
5166 KMF_ENCODE_FORMAT format;
5167 char *crlfile = NULL;
5168 BIO *in = NULL;
5169 BIO *mem = NULL;
5170 long len;
5171 char *memptr;
5172 char *data = NULL;
5173 char **crldata;
5174 char *crlfilename, *dirpath;
5175
5176 if (numattr == 0 || attrlist == NULL) {
5177 return (KMF_ERR_BAD_PARAMETER);
5178 }
5179 crlfilename = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR,
5180 attrlist, numattr);
5181 if (crlfilename == NULL)
5182 return (KMF_ERR_BAD_CRLFILE);
5183
5184 crldata = (char **)kmf_get_attr_ptr(KMF_CRL_DATA_ATTR,
5185 attrlist, numattr);
5186
5187 if (crldata == NULL)
5188 return (KMF_ERR_BAD_PARAMETER);
5189
5190 dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
5191
5192 crlfile = get_fullpath(dirpath, crlfilename);
5193
5194 if (crlfile == NULL)
5195 return (KMF_ERR_BAD_CRLFILE);
5196
5197 if (isdir(crlfile)) {
5198 free(crlfile);
5199 return (KMF_ERR_BAD_CRLFILE);
5200 }
5201
5202 ret = kmf_is_crl_file(handle, crlfile, &format);
5203 if (ret != KMF_OK) {
5204 free(crlfile);
5205 return (ret);
5206 }
5207
5208 if (bio_err == NULL)
5209 bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
5210
5211 in = BIO_new_file(crlfile, "rb");
5212 if (in == NULL) {
5213 SET_ERROR(kmfh, ERR_get_error());
5214 ret = KMF_ERR_OPEN_FILE;
5215 goto end;
5216 }
5217
5218 if (format == KMF_FORMAT_ASN1) {
5219 x = d2i_X509_CRL_bio(in, NULL);
5220 } else if (format == KMF_FORMAT_PEM) {
5221 x = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
5222 }
5223
5224 if (x == NULL) { /* should not happen */
5225 SET_ERROR(kmfh, ERR_get_error());
5226 ret = KMF_ERR_OPEN_FILE;
5227 goto end;
5228 }
5229
5230 mem = BIO_new(BIO_s_mem());
5231 if (mem == NULL) {
5232 SET_ERROR(kmfh, ERR_get_error());
5233 ret = KMF_ERR_MEMORY;
5234 goto end;
5235 }
5236
5237 (void) X509_CRL_print(mem, x);
5238 len = BIO_get_mem_data(mem, &memptr);
5239 if (len <= 0) {
5240 SET_ERROR(kmfh, ERR_get_error());
5241 ret = KMF_ERR_MEMORY;
5242 goto end;
5243 }
5244
5245 data = malloc(len + 1);
5246 if (data == NULL) {
5247 ret = KMF_ERR_MEMORY;
5248 goto end;
5249 }
5250
5251 (void) memcpy(data, memptr, len);
5252 data[len] = '\0';
5253 *crldata = data;
5254
5255 end:
5256 if (x != NULL)
5257 X509_CRL_free(x);
5258
5259 if (crlfile != NULL)
5260 free(crlfile);
5261
5262 if (in != NULL)
5263 (void) BIO_free(in);
5264
5265 if (mem != NULL)
5266 (void) BIO_free(mem);
5267
5268 return (ret);
5269 }
5270
5271 KMF_RETURN
OpenSSL_DeleteCRL(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)5272 OpenSSL_DeleteCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
5273 {
5274 KMF_RETURN ret = KMF_OK;
5275 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
5276 KMF_ENCODE_FORMAT format;
5277 char *crlfile = NULL;
5278 BIO *in = NULL;
5279 char *crlfilename, *dirpath;
5280
5281 if (numattr == 0 || attrlist == NULL) {
5282 return (KMF_ERR_BAD_PARAMETER);
5283 }
5284
5285 crlfilename = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR,
5286 attrlist, numattr);
5287
5288 if (crlfilename == NULL)
5289 return (KMF_ERR_BAD_CRLFILE);
5290
5291 dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
5292
5293 crlfile = get_fullpath(dirpath, crlfilename);
5294
5295 if (crlfile == NULL)
5296 return (KMF_ERR_BAD_CRLFILE);
5297
5298 if (isdir(crlfile)) {
5299 ret = KMF_ERR_BAD_CRLFILE;
5300 goto end;
5301 }
5302
5303 ret = kmf_is_crl_file(handle, crlfile, &format);
5304 if (ret != KMF_OK)
5305 goto end;
5306
5307 if (unlink(crlfile) != 0) {
5308 SET_SYS_ERROR(kmfh, errno);
5309 ret = KMF_ERR_INTERNAL;
5310 goto end;
5311 }
5312
5313 end:
5314 if (in != NULL)
5315 (void) BIO_free(in);
5316 if (crlfile != NULL)
5317 free(crlfile);
5318
5319 return (ret);
5320 }
5321
5322 KMF_RETURN
OpenSSL_FindCertInCRL(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)5323 OpenSSL_FindCertInCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
5324 {
5325 KMF_RETURN ret = KMF_OK;
5326 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
5327 KMF_ENCODE_FORMAT format;
5328 BIO *in = NULL;
5329 X509 *xcert = NULL;
5330 X509_CRL *xcrl = NULL;
5331 STACK_OF(X509_REVOKED) *revoke_stack = NULL;
5332 X509_REVOKED *revoke;
5333 int i;
5334 char *crlfilename, *crlfile, *dirpath, *certfile;
5335
5336 if (numattr == 0 || attrlist == NULL) {
5337 return (KMF_ERR_BAD_PARAMETER);
5338 }
5339
5340 crlfilename = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR,
5341 attrlist, numattr);
5342
5343 if (crlfilename == NULL)
5344 return (KMF_ERR_BAD_CRLFILE);
5345
5346 certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr);
5347 if (certfile == NULL)
5348 return (KMF_ERR_BAD_CRLFILE);
5349
5350 dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
5351
5352 crlfile = get_fullpath(dirpath, crlfilename);
5353
5354 if (crlfile == NULL)
5355 return (KMF_ERR_BAD_CRLFILE);
5356
5357 if (isdir(crlfile)) {
5358 ret = KMF_ERR_BAD_CRLFILE;
5359 goto end;
5360 }
5361
5362 ret = kmf_is_crl_file(handle, crlfile, &format);
5363 if (ret != KMF_OK)
5364 goto end;
5365
5366 /* Read the CRL file and load it into a X509_CRL structure */
5367 in = BIO_new_file(crlfilename, "rb");
5368 if (in == NULL) {
5369 SET_ERROR(kmfh, ERR_get_error());
5370 ret = KMF_ERR_OPEN_FILE;
5371 goto end;
5372 }
5373
5374 if (format == KMF_FORMAT_ASN1) {
5375 xcrl = d2i_X509_CRL_bio(in, NULL);
5376 } else if (format == KMF_FORMAT_PEM) {
5377 xcrl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
5378 }
5379
5380 if (xcrl == NULL) {
5381 SET_ERROR(kmfh, ERR_get_error());
5382 ret = KMF_ERR_BAD_CRLFILE;
5383 goto end;
5384 }
5385 (void) BIO_free(in);
5386
5387 /* Read the Certificate file and load it into a X509 structure */
5388 ret = kmf_is_cert_file(handle, certfile, &format);
5389 if (ret != KMF_OK)
5390 goto end;
5391
5392 in = BIO_new_file(certfile, "rb");
5393 if (in == NULL) {
5394 SET_ERROR(kmfh, ERR_get_error());
5395 ret = KMF_ERR_OPEN_FILE;
5396 goto end;
5397 }
5398
5399 if (format == KMF_FORMAT_ASN1) {
5400 xcert = d2i_X509_bio(in, NULL);
5401 } else if (format == KMF_FORMAT_PEM) {
5402 xcert = PEM_read_bio_X509(in, NULL, NULL, NULL);
5403 }
5404
5405 if (xcert == NULL) {
5406 SET_ERROR(kmfh, ERR_get_error());
5407 ret = KMF_ERR_BAD_CERTFILE;
5408 goto end;
5409 }
5410
5411 /* Check if the certificate and the CRL have same issuer */
5412 if (X509_NAME_cmp(xcert->cert_info->issuer, xcrl->crl->issuer) != 0) {
5413 ret = KMF_ERR_ISSUER;
5414 goto end;
5415 }
5416
5417 /* Check to see if the certificate serial number is revoked */
5418 revoke_stack = X509_CRL_get_REVOKED(xcrl);
5419 if (sk_X509_REVOKED_num(revoke_stack) <= 0) {
5420 /* No revoked certificates in the CRL file */
5421 SET_ERROR(kmfh, ERR_get_error());
5422 ret = KMF_ERR_EMPTY_CRL;
5423 goto end;
5424 }
5425
5426 for (i = 0; i < sk_X509_REVOKED_num(revoke_stack); i++) {
5427 /* LINTED E_BAD_PTR_CAST_ALIGN */
5428 revoke = sk_X509_REVOKED_value(revoke_stack, i);
5429 if (ASN1_INTEGER_cmp(xcert->cert_info->serialNumber,
5430 revoke->serialNumber) == 0) {
5431 break;
5432 }
5433 }
5434
5435 if (i < sk_X509_REVOKED_num(revoke_stack)) {
5436 ret = KMF_OK;
5437 } else {
5438 ret = KMF_ERR_NOT_REVOKED;
5439 }
5440
5441 end:
5442 if (in != NULL)
5443 (void) BIO_free(in);
5444 if (xcrl != NULL)
5445 X509_CRL_free(xcrl);
5446 if (xcert != NULL)
5447 X509_free(xcert);
5448
5449 return (ret);
5450 }
5451
5452 KMF_RETURN
OpenSSL_VerifyCRLFile(KMF_HANDLE_T handle,char * crlname,KMF_DATA * tacert)5453 OpenSSL_VerifyCRLFile(KMF_HANDLE_T handle, char *crlname, KMF_DATA *tacert)
5454 {
5455 KMF_RETURN ret = KMF_OK;
5456 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
5457 BIO *bcrl = NULL;
5458 X509_CRL *xcrl = NULL;
5459 X509 *xcert = NULL;
5460 EVP_PKEY *pkey;
5461 int sslret;
5462 KMF_ENCODE_FORMAT crl_format;
5463 unsigned char *p;
5464 long len;
5465
5466 if (handle == NULL || crlname == NULL || tacert == NULL) {
5467 return (KMF_ERR_BAD_PARAMETER);
5468 }
5469
5470 ret = kmf_get_file_format(crlname, &crl_format);
5471 if (ret != KMF_OK)
5472 return (ret);
5473
5474 bcrl = BIO_new_file(crlname, "rb");
5475 if (bcrl == NULL) {
5476 SET_ERROR(kmfh, ERR_get_error());
5477 ret = KMF_ERR_OPEN_FILE;
5478 goto cleanup;
5479 }
5480
5481 if (crl_format == KMF_FORMAT_ASN1) {
5482 xcrl = d2i_X509_CRL_bio(bcrl, NULL);
5483 } else if (crl_format == KMF_FORMAT_PEM) {
5484 xcrl = PEM_read_bio_X509_CRL(bcrl, NULL, NULL, NULL);
5485 } else {
5486 ret = KMF_ERR_BAD_PARAMETER;
5487 goto cleanup;
5488 }
5489
5490 if (xcrl == NULL) {
5491 SET_ERROR(kmfh, ERR_get_error());
5492 ret = KMF_ERR_BAD_CRLFILE;
5493 goto cleanup;
5494 }
5495
5496 p = tacert->Data;
5497 len = tacert->Length;
5498 xcert = d2i_X509(NULL, (const uchar_t **)&p, len);
5499
5500 if (xcert == NULL) {
5501 SET_ERROR(kmfh, ERR_get_error());
5502 ret = KMF_ERR_BAD_CERTFILE;
5503 goto cleanup;
5504 }
5505
5506 /* Get issuer certificate public key */
5507 pkey = X509_get_pubkey(xcert);
5508 if (pkey == NULL) {
5509 SET_ERROR(kmfh, ERR_get_error());
5510 ret = KMF_ERR_BAD_CERT_FORMAT;
5511 goto cleanup;
5512 }
5513
5514 /* Verify CRL signature */
5515 sslret = X509_CRL_verify(xcrl, pkey);
5516 EVP_PKEY_free(pkey);
5517 if (sslret > 0) {
5518 ret = KMF_OK;
5519 } else {
5520 SET_ERROR(kmfh, sslret);
5521 ret = KMF_ERR_BAD_CRLFILE;
5522 }
5523
5524 cleanup:
5525 if (bcrl != NULL)
5526 (void) BIO_free(bcrl);
5527
5528 if (xcrl != NULL)
5529 X509_CRL_free(xcrl);
5530
5531 if (xcert != NULL)
5532 X509_free(xcert);
5533
5534 return (ret);
5535
5536 }
5537
5538 KMF_RETURN
OpenSSL_CheckCRLDate(KMF_HANDLE_T handle,char * crlname)5539 OpenSSL_CheckCRLDate(KMF_HANDLE_T handle, char *crlname)
5540 {
5541 KMF_RETURN ret = KMF_OK;
5542 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
5543 KMF_ENCODE_FORMAT crl_format;
5544 BIO *bcrl = NULL;
5545 X509_CRL *xcrl = NULL;
5546 int i;
5547
5548 if (handle == NULL || crlname == NULL) {
5549 return (KMF_ERR_BAD_PARAMETER);
5550 }
5551
5552 ret = kmf_is_crl_file(handle, crlname, &crl_format);
5553 if (ret != KMF_OK)
5554 return (ret);
5555
5556 bcrl = BIO_new_file(crlname, "rb");
5557 if (bcrl == NULL) {
5558 SET_ERROR(kmfh, ERR_get_error());
5559 ret = KMF_ERR_OPEN_FILE;
5560 goto cleanup;
5561 }
5562
5563 if (crl_format == KMF_FORMAT_ASN1)
5564 xcrl = d2i_X509_CRL_bio(bcrl, NULL);
5565 else if (crl_format == KMF_FORMAT_PEM)
5566 xcrl = PEM_read_bio_X509_CRL(bcrl, NULL, NULL, NULL);
5567
5568 if (xcrl == NULL) {
5569 SET_ERROR(kmfh, ERR_get_error());
5570 ret = KMF_ERR_BAD_CRLFILE;
5571 goto cleanup;
5572 }
5573 i = X509_cmp_time(X509_CRL_get_lastUpdate(xcrl), NULL);
5574 if (i >= 0) {
5575 ret = KMF_ERR_VALIDITY_PERIOD;
5576 goto cleanup;
5577 }
5578 if (X509_CRL_get_nextUpdate(xcrl)) {
5579 i = X509_cmp_time(X509_CRL_get_nextUpdate(xcrl), NULL);
5580
5581 if (i <= 0) {
5582 ret = KMF_ERR_VALIDITY_PERIOD;
5583 goto cleanup;
5584 }
5585 }
5586
5587 ret = KMF_OK;
5588
5589 cleanup:
5590 if (bcrl != NULL)
5591 (void) BIO_free(bcrl);
5592
5593 if (xcrl != NULL)
5594 X509_CRL_free(xcrl);
5595
5596 return (ret);
5597 }
5598