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