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