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