1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 *
21 * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
22 */
23
24 #include <stdio.h>
25 #include <link.h>
26 #include <fcntl.h>
27 #include <ctype.h>
28 #include <sys/param.h>
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <sys/socket.h>
32 #include <ber_der.h>
33 #include <kmfapiP.h>
34 #include <pem_encode.h>
35 #include <libgen.h>
36 #include <cryptoutil.h>
37
38 #define CERTFILE_TEMPNAME "/tmp/user.certXXXXXX"
39 #define CRLFILE_TEMPNAME "/tmp/crlXXXXXX"
40 #define X509_FORMAT_VERSION 2
41
42 static KMF_RETURN
43 sign_cert(KMF_HANDLE_T, const KMF_DATA *, KMF_KEY_HANDLE *,
44 KMF_OID *, KMF_DATA *);
45
46 static KMF_RETURN
47 verify_cert_with_key(KMF_HANDLE_T, KMF_DATA *, const KMF_DATA *);
48
49 static KMF_RETURN
50 verify_cert_with_cert(KMF_HANDLE_T, const KMF_DATA *, const KMF_DATA *);
51
52 static KMF_RETURN
get_keyalg_from_cert(KMF_DATA * cert,KMF_KEY_ALG * keyalg)53 get_keyalg_from_cert(KMF_DATA *cert, KMF_KEY_ALG *keyalg)
54 {
55 KMF_RETURN rv;
56 KMF_X509_CERTIFICATE *SignerCert = NULL;
57 KMF_ALGORITHM_INDEX AlgorithmId;
58
59 rv = DerDecodeSignedCertificate(cert, &SignerCert);
60
61 if (rv != KMF_OK)
62 return (rv);
63
64 /* Get the algorithm info from the signer certificate */
65 AlgorithmId = x509_algoid_to_algid(
66 &SignerCert->signature.algorithmIdentifier.algorithm);
67
68 switch (AlgorithmId) {
69 case KMF_ALGID_MD5WithRSA:
70 case KMF_ALGID_SHA1WithRSA:
71 case KMF_ALGID_SHA256WithRSA:
72 case KMF_ALGID_SHA384WithRSA:
73 case KMF_ALGID_SHA512WithRSA:
74 *keyalg = KMF_RSA;
75 break;
76 case KMF_ALGID_SHA1WithDSA:
77 case KMF_ALGID_SHA256WithDSA:
78 *keyalg = KMF_DSA;
79 break;
80 case KMF_ALGID_SHA1WithECDSA:
81 case KMF_ALGID_SHA256WithECDSA:
82 case KMF_ALGID_SHA384WithECDSA:
83 case KMF_ALGID_SHA512WithECDSA:
84 case KMF_ALGID_ECDSA:
85 *keyalg = KMF_ECDSA;
86 break;
87 default:
88 rv = KMF_ERR_BAD_ALGORITHM;
89 }
90
91 kmf_free_signed_cert(SignerCert);
92 free(SignerCert);
93 return (rv);
94 }
95
96 /*
97 * Name: kmf_find_prikey_by_cert
98 *
99 * Description:
100 * This function finds the corresponding private key in keystore
101 * for a certificate
102 */
103 KMF_RETURN
kmf_find_prikey_by_cert(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)104 kmf_find_prikey_by_cert(KMF_HANDLE_T handle, int numattr,
105 KMF_ATTRIBUTE *attrlist)
106 {
107 KMF_PLUGIN *plugin;
108 KMF_RETURN ret = KMF_OK;
109 KMF_KEYSTORE_TYPE kstype;
110 KMF_KEY_ALG keyalg;
111 KMF_KEY_HANDLE *key = NULL;
112 KMF_DATA *cert = NULL;
113
114 KMF_ATTRIBUTE_TESTER required_attrs[] = {
115 {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)},
116 {KMF_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), sizeof (KMF_DATA)},
117 {KMF_KEY_HANDLE_ATTR, TRUE, sizeof (KMF_KEY_HANDLE),
118 sizeof (KMF_KEY_HANDLE)}
119 };
120
121 int num_req_attrs = sizeof (required_attrs) /
122 sizeof (KMF_ATTRIBUTE_TESTER);
123
124 if (handle == NULL)
125 return (KMF_ERR_BAD_PARAMETER);
126
127 CLEAR_ERROR(handle, ret);
128
129 ret = test_attributes(num_req_attrs, required_attrs,
130 0, NULL, numattr, attrlist);
131 if (ret != KMF_OK)
132 return (ret);
133
134 /*
135 * First, get the key algorithm info from the certificate and saves it
136 * in the returned key handle.
137 */
138 cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr);
139 if (cert == NULL)
140 return (KMF_ERR_BAD_PARAMETER);
141
142 ret = get_keyalg_from_cert(cert, &keyalg);
143 if (ret != KMF_OK)
144 return (ret);
145
146 key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
147 if (key == NULL)
148 return (KMF_ERR_BAD_PARAMETER);
149 key->keyalg = keyalg;
150
151 /* Call the plugin to do the work. */
152 ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr,
153 &kstype, NULL);
154 if (ret != KMF_OK)
155 return (ret);
156
157 plugin = FindPlugin(handle, kstype);
158 if (plugin == NULL || plugin->funclist->FindPrikeyByCert == NULL)
159 return (KMF_ERR_PLUGIN_NOTFOUND);
160
161 return (plugin->funclist->FindPrikeyByCert(handle, numattr, attrlist));
162 }
163
164
165 KMF_RETURN
check_key_usage(void * handle,const KMF_DATA * cert,const KMF_KU_PURPOSE purpose)166 check_key_usage(void *handle,
167 const KMF_DATA *cert,
168 const KMF_KU_PURPOSE purpose)
169 {
170 KMF_X509EXT_BASICCONSTRAINTS constraint;
171 KMF_BOOL critical = B_FALSE;
172 KMF_X509EXT_KEY_USAGE keyusage;
173 KMF_RETURN ret = KMF_OK;
174
175 if (handle == NULL || cert == NULL)
176 return (KMF_ERR_BAD_PARAMETER);
177
178 (void) memset(&constraint, 0, sizeof (KMF_X509EXT_BASICCONSTRAINTS));
179 (void) memset(&keyusage, 0, sizeof (KMF_X509EXT_KEY_USAGE));
180
181 ret = kmf_get_cert_ku(cert, &keyusage);
182 if (ret != KMF_OK)
183 /*
184 * If absent or error, the cert is assumed to be invalid
185 * for all key usage checking.
186 */
187 return (ret);
188
189 switch (purpose) {
190 case KMF_KU_SIGN_CERT:
191 /*
192 * RFC 3280:
193 * The keyCertSign bit is asserted when the subject
194 * public key is used for verifying a signature on
195 * public key certificates. If the keyCertSign bit
196 * is asserted, then the cA bit in the basic constraints
197 * extension (section 4.2.1.10) MUST also be asserted.
198 * The basic constraints extension MUST appear as a
199 * critical extension in all CA certificates that
200 * contain public keys used to validate digital
201 * signatures on certificates.
202 */
203 if (keyusage.KeyUsageBits & KMF_keyCertSign) {
204 ret = kmf_get_cert_basic_constraint(cert,
205 &critical, &constraint);
206
207 if (ret != KMF_OK)
208 return (ret);
209
210 if ((!critical) || (!constraint.cA))
211 return (KMF_ERR_KEYUSAGE);
212 } else {
213 return (KMF_ERR_KEYUSAGE);
214 }
215 break;
216 case KMF_KU_SIGN_DATA:
217 /*
218 * RFC 3280:
219 * The digitalSignature bit is asserted when the subject
220 * public key is used with a digital signature mechanism
221 * to support security services other than certificate
222 * signing(bit 5), or CRL signing(bit 6).
223 */
224 if (!(keyusage.KeyUsageBits & KMF_digitalSignature))
225 return (KMF_ERR_KEYUSAGE);
226 break;
227 case KMF_KU_ENCRYPT_DATA:
228 /*
229 * RFC 3280:
230 * The dataEncipherment bit is asserted when the subject
231 * public key is used for enciphering user data, other than
232 * cryptographic keys.
233 */
234 if (!(keyusage.KeyUsageBits & KMF_dataEncipherment))
235 return (KMF_ERR_KEYUSAGE);
236 break;
237 default:
238 return (KMF_ERR_BAD_PARAMETER);
239 }
240
241 return (KMF_OK);
242 }
243
244 KMF_RETURN
kmf_find_cert(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)245 kmf_find_cert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
246 {
247 KMF_PLUGIN *plugin;
248 KMF_RETURN ret = KMF_OK;
249 KMF_KEYSTORE_TYPE kstype;
250 KMF_ATTRIBUTE_TESTER required_attrs[] = {
251 {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)},
252 {KMF_COUNT_ATTR, FALSE, sizeof (uint32_t), sizeof (uint32_t)}
253 };
254 int num_req_attrs = sizeof (required_attrs) /
255 sizeof (KMF_ATTRIBUTE_TESTER);
256
257 if (handle == NULL)
258 return (KMF_ERR_BAD_PARAMETER);
259
260 CLEAR_ERROR(handle, ret);
261
262 ret = test_attributes(num_req_attrs, required_attrs,
263 0, NULL, numattr, attrlist);
264 if (ret != KMF_OK)
265 return (ret);
266
267 ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr,
268 &kstype, NULL);
269 if (ret != KMF_OK)
270 return (ret);
271
272 plugin = FindPlugin(handle, kstype);
273 if (plugin == NULL || plugin->funclist->FindCert == NULL)
274 return (KMF_ERR_PLUGIN_NOTFOUND);
275
276 return (plugin->funclist->FindCert(handle, numattr, attrlist));
277 }
278
279 #define NODATA(d) (d.Data == NULL || d.Length == NULL)
280
281 KMF_RETURN
kmf_encode_cert_record(KMF_X509_CERTIFICATE * CertData,KMF_DATA * encodedCert)282 kmf_encode_cert_record(KMF_X509_CERTIFICATE *CertData, KMF_DATA *encodedCert)
283 {
284 KMF_RETURN ret;
285 KMF_X509_TBS_CERT *tbs_cert;
286
287 if (CertData == NULL || encodedCert == NULL)
288 return (KMF_ERR_BAD_PARAMETER);
289
290 /*
291 * Validate that all required fields are present.
292 */
293 tbs_cert = &(CertData->certificate);
294 if (NODATA(tbs_cert->version) ||
295 NODATA(tbs_cert->signature.algorithm) ||
296 NODATA(tbs_cert->subjectPublicKeyInfo.subjectPublicKey) ||
297 tbs_cert->serialNumber.val == NULL ||
298 tbs_cert->serialNumber.len == 0 ||
299 tbs_cert->subject.numberOfRDNs == 0 ||
300 tbs_cert->issuer.numberOfRDNs == 0) {
301 return (KMF_ERR_INCOMPLETE_TBS_CERT);
302 }
303
304 encodedCert->Length = 0;
305 encodedCert->Data = NULL;
306
307 /* Pack the new certificate */
308 ret = DerEncodeSignedCertificate(CertData, encodedCert);
309
310 return (ret);
311 }
312
313 /*
314 * This function is used to setup the attribute list before calling
315 * kmf_find_prikey_by_cert(). This function is used by
316 * kmf_decrypt_with_cert
317 * kmf_sign_cert
318 * kmf_sign_data
319 *
320 * The attribute list in these callers contain all the attributes
321 * needed by kmf_find_prikey_by_cert(), except the
322 * KMF_KEY_HANDLE attribute and the KMF_CERT_DATA_ATTR attribute.
323 * These 2 attributes need to be added or reset.
324 *
325 * The caller should free the new_attrlist after use it.
326 */
327 static KMF_RETURN
setup_findprikey_attrlist(KMF_ATTRIBUTE * src_attrlist,int src_num,KMF_ATTRIBUTE ** new_attrlist,int * new_num,KMF_KEY_HANDLE * key,KMF_DATA * cert)328 setup_findprikey_attrlist(KMF_ATTRIBUTE *src_attrlist, int src_num,
329 KMF_ATTRIBUTE **new_attrlist, int *new_num, KMF_KEY_HANDLE *key,
330 KMF_DATA *cert)
331 {
332 KMF_ATTRIBUTE *attrlist = NULL;
333 int cur_num = src_num;
334 int index;
335 int i;
336
337 if (src_attrlist == NULL || new_num == NULL || key == NULL ||
338 cert == NULL)
339 return (KMF_ERR_BAD_PARAMETER);
340
341 /* Create a new attribute list with 2 more elements */
342 attrlist = (KMF_ATTRIBUTE *) malloc(
343 (src_num + 2) * sizeof (KMF_ATTRIBUTE));
344 if (attrlist == NULL)
345 return (KMF_ERR_MEMORY);
346
347 /* Copy the src_attrlist to the new list */
348 for (i = 0; i < src_num; i++) {
349 attrlist[i].type = src_attrlist[i].type;
350 attrlist[i].pValue = src_attrlist[i].pValue;
351 attrlist[i].valueLen = src_attrlist[i].valueLen;
352 }
353
354 /* Add or reset the key handle attribute */
355 index = kmf_find_attr(KMF_KEY_HANDLE_ATTR, attrlist, cur_num);
356 if (index == -1) {
357 /* not found; add it */
358 kmf_set_attr_at_index(attrlist, cur_num,
359 KMF_KEY_HANDLE_ATTR, key, sizeof (KMF_KEY_HANDLE));
360 cur_num++;
361 } else {
362 /* found; just reset it */
363 kmf_set_attr_at_index(attrlist, index,
364 KMF_KEY_HANDLE_ATTR, key, sizeof (KMF_KEY_HANDLE));
365 }
366
367 /* add or reset the cert data attribute */
368 index = kmf_find_attr(KMF_CERT_DATA_ATTR, attrlist, cur_num);
369 if (index == -1) {
370 /* not found; add it */
371 kmf_set_attr_at_index(attrlist, cur_num,
372 KMF_CERT_DATA_ATTR, cert, sizeof (KMF_DATA));
373 cur_num++;
374 } else {
375 /* found; just reset it */
376 kmf_set_attr_at_index(attrlist, index,
377 KMF_CERT_DATA_ATTR, cert, sizeof (KMF_DATA));
378 }
379
380 *new_attrlist = attrlist;
381 *new_num = cur_num;
382 return (KMF_OK);
383 }
384
385 /*
386 * Determine a default signature type to use based on
387 * the key algorithm.
388 */
389 static KMF_OID *
get_default_signoid(KMF_KEY_HANDLE * key)390 get_default_signoid(KMF_KEY_HANDLE *key)
391 {
392 KMF_OID *oid;
393
394 switch (key->keyalg) {
395 case KMF_RSA:
396 oid = (KMF_OID *)&KMFOID_SHA256WithRSA;
397 break;
398 case KMF_DSA:
399 /* NSS doesnt support DSA-SHA2 hashes yet */
400 if (key->kstype == KMF_KEYSTORE_NSS)
401 oid = (KMF_OID *)&KMFOID_X9CM_DSAWithSHA1;
402 else
403 oid = (KMF_OID *)&KMFOID_SHA256WithDSA;
404 break;
405 case KMF_ECDSA:
406 oid = (KMF_OID *)&KMFOID_SHA256WithECDSA;
407 break;
408 default:
409 oid = NULL;
410 break;
411 }
412 return (oid);
413 }
414
415 /*
416 * This is to check to see if a certificate being signed has
417 * the keyCertSign KeyUsage bit set, and if so, make sure the
418 * "BasicConstraints" extension is also set accordingly.
419 */
420 static KMF_RETURN
check_for_basic_constraint(KMF_DATA * cert)421 check_for_basic_constraint(KMF_DATA *cert)
422 {
423 KMF_RETURN rv = KMF_OK;
424 KMF_X509EXT_KEY_USAGE keyUsage;
425 KMF_X509_CERTIFICATE *x509cert = NULL;
426
427 rv = kmf_get_cert_ku((const KMF_DATA *)cert, &keyUsage);
428 if (rv == KMF_OK) {
429 KMF_X509EXT_BASICCONSTRAINTS basicConstraint;
430 KMF_BOOL critical;
431 /* If keyCertSign is set, look for basicConstraints */
432 if (keyUsage.KeyUsageBits & KMF_keyCertSign)
433 rv = kmf_get_cert_basic_constraint(
434 (const KMF_DATA *)cert,
435 &critical, &basicConstraint);
436
437 /*
438 * If we got KMF_OK (or an error), then return
439 * because the extension is already present. We
440 * only want to continue with this function if
441 * the extension is NOT found.
442 */
443 if (rv != KMF_ERR_EXTENSION_NOT_FOUND)
444 return (rv);
445
446 /*
447 * Don't limit the pathLen (for now).
448 * This should probably be a policy setting in the
449 * future.
450 */
451 basicConstraint.cA = TRUE;
452 basicConstraint.pathLenConstraintPresent = FALSE;
453
454 /*
455 * Decode the DER cert data into the internal
456 * X.509 structure we need to set extensions.
457 */
458 rv = DerDecodeSignedCertificate(cert, &x509cert);
459 if (rv != KMF_OK)
460 return (rv);
461 /*
462 * Add the missing basic constraint.
463 */
464 rv = kmf_set_cert_basic_constraint(x509cert,
465 TRUE, &basicConstraint);
466 if (rv != KMF_OK) {
467 kmf_free_signed_cert(x509cert);
468 free(x509cert);
469 return (rv);
470 }
471 /* Free the old cert data record */
472 kmf_free_data(cert);
473
474 /* Re-encode the cert with the extension */
475 rv = kmf_encode_cert_record(x509cert, cert);
476
477 /* cleanup */
478 kmf_free_signed_cert(x509cert);
479 free(x509cert);
480 }
481 if (rv == KMF_ERR_EXTENSION_NOT_FOUND)
482 rv = KMF_OK;
483
484 return (rv);
485 }
486
487 /*
488 * Name: kmf_sign_cert
489 *
490 * Description:
491 * This function signs a certificate using the signer cert and
492 * returns a signed and DER-encoded certificate.
493 *
494 * The following types of certificate data can be submitted to be signed:
495 * KMF_TBS_CERT_DATA_ATTR - a KMF_DATA ptr is provided in the attrlist
496 * and is signed directly.
497 * KMF_X509_CERTIFICATE_ATTR - a KMF_X509_CERTIFICATE record is provided
498 * in the attribute list. This is converted to raw KMF_DATA
499 * prior to signing.
500 *
501 * The key for the signing operation can be provided as a KMF_KEY_HANDLE_ATTR
502 * or the caller may choose to provide a KMF_SIGNER_CERT_ATTR (KMF_DATA *).
503 * If the latter, this function will then attempt to find the private key
504 * associated with the certificate. The private key must be stored in
505 * the same keystore as the signer certificate.
506 */
507 KMF_RETURN
kmf_sign_cert(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)508 kmf_sign_cert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
509 {
510 KMF_RETURN ret;
511 int new_numattr = numattr + 1;
512 KMF_ATTRIBUTE *new_attrlist = NULL;
513 KMF_DATA *signer_cert = NULL;
514 KMF_DATA *tbs_cert = NULL; /* to be signed cert */
515 KMF_DATA *signed_cert = NULL;
516 KMF_DATA unsignedCert = { 0, NULL };
517 KMF_KEY_HANDLE sign_key, *sign_key_ptr;
518 int freethekey = 0;
519 KMF_POLICY_RECORD *policy;
520 KMF_OID *oid = NULL;
521 KMF_X509_CERTIFICATE *x509cert;
522 KMF_X509_TBS_CERT *decodedTbsCert = NULL;
523 KMF_ATTRIBUTE_TESTER required_attrs[] = {
524 {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)},
525 {KMF_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), sizeof (KMF_DATA)}
526 };
527 int num_req_attrs = sizeof (required_attrs) /
528 sizeof (KMF_ATTRIBUTE_TESTER);
529
530 if (handle == NULL)
531 return (KMF_ERR_BAD_PARAMETER);
532
533 CLEAR_ERROR(handle, ret);
534
535 ret = test_attributes(num_req_attrs, required_attrs,
536 0, NULL, numattr, attrlist);
537 if (ret != KMF_OK)
538 return (ret);
539
540 /* Get the signer cert and check its keyUsage */
541 signer_cert = kmf_get_attr_ptr(KMF_SIGNER_CERT_DATA_ATTR, attrlist,
542 numattr);
543 sign_key_ptr = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist,
544 numattr);
545 /*
546 * Only accept 1 or the other, not both.
547 */
548 if (signer_cert == NULL && sign_key_ptr == NULL)
549 return (KMF_ERR_BAD_PARAMETER);
550 if (signer_cert != NULL && sign_key_ptr != NULL)
551 return (KMF_ERR_BAD_PARAMETER);
552
553 oid = kmf_get_attr_ptr(KMF_OID_ATTR, attrlist, numattr);
554 if (oid == NULL) {
555 /*
556 * If the signature OID was not given, check
557 * for an algorithm index identifier instead.
558 */
559 KMF_ALGORITHM_INDEX AlgId;
560 ret = kmf_get_attr(KMF_ALGORITHM_INDEX_ATTR, attrlist, numattr,
561 &AlgId, NULL);
562 if (ret == KMF_OK)
563 oid = x509_algid_to_algoid(AlgId);
564 }
565
566 if (signer_cert != NULL) {
567 policy = handle->policy;
568 ret = check_key_usage(handle, signer_cert, KMF_KU_SIGN_CERT);
569 if (ret == KMF_ERR_EXTENSION_NOT_FOUND && policy->ku_bits == 0)
570 ret = KMF_OK;
571 if (ret != KMF_OK)
572 return (ret);
573
574 /*
575 * Find the private key from the signer certificate by calling
576 * kmf_find_prikey_by_cert().
577 */
578 ret = setup_findprikey_attrlist(attrlist, numattr,
579 &new_attrlist, &new_numattr, &sign_key, signer_cert);
580 if (ret != KMF_OK)
581 goto out;
582
583 ret = kmf_find_prikey_by_cert(handle, new_numattr,
584 new_attrlist);
585 if (ret != KMF_OK) {
586 goto out;
587 }
588 sign_key_ptr = &sign_key;
589 freethekey = 1;
590 }
591
592 tbs_cert = kmf_get_attr_ptr(KMF_TBS_CERT_DATA_ATTR, attrlist,
593 numattr);
594 if (tbs_cert == NULL) {
595 x509cert = kmf_get_attr_ptr(KMF_X509_CERTIFICATE_ATTR, attrlist,
596 numattr);
597 if (x509cert == NULL) {
598 ret = KMF_ERR_BAD_PARAMETER;
599 goto out;
600 }
601
602 ret = kmf_encode_cert_record(x509cert, &unsignedCert);
603 if (ret != KMF_OK)
604 goto out;
605
606 tbs_cert = &unsignedCert;
607 }
608 /*
609 * Check for the keyCertSign bit in the KeyUsage extn. If it is set,
610 * then the basicConstraints must also be present and be
611 * marked critical.
612 */
613 ret = check_for_basic_constraint(tbs_cert);
614 if (ret)
615 goto out;
616
617 if (oid == NULL) {
618 /*
619 * If OID is not known yet, use a default value
620 * based on the signers key type.
621 */
622 oid = get_default_signoid(sign_key_ptr);
623 }
624
625 signed_cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist,
626 numattr);
627 if (signed_cert == NULL) {
628 ret = KMF_ERR_BAD_PARAMETER;
629 goto out;
630 }
631
632 ret = sign_cert(handle, tbs_cert, sign_key_ptr, oid, signed_cert);
633 out:
634 if (new_attrlist)
635 (void) free(new_attrlist);
636
637 /* If we had to find the key, free it here. */
638 if (freethekey)
639 kmf_free_kmf_key(handle, &sign_key);
640
641 kmf_free_data(&unsignedCert);
642 if (decodedTbsCert != NULL) {
643 kmf_free_tbs_cert(decodedTbsCert);
644 free(decodedTbsCert);
645 }
646 return (ret);
647 }
648
649 /*
650 * Name: kmf_sign_data
651 *
652 * Description:
653 * This function signs a block of data using the signer cert and
654 * returns the the signature in output
655 */
656 KMF_RETURN
kmf_sign_data(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)657 kmf_sign_data(KMF_HANDLE_T handle, int numattr,
658 KMF_ATTRIBUTE *attrlist)
659 {
660 KMF_PLUGIN *plugin;
661 KMF_RETURN ret = KMF_OK;
662 KMF_ATTRIBUTE *new_attrlist = NULL;
663 int new_numattr = numattr;
664 KMF_DATA *signer_cert = NULL;
665 KMF_DATA *tbs_data = NULL; /* to be signed data */
666 KMF_DATA *output = NULL;
667 KMF_KEY_HANDLE sign_key, *sign_key_ptr;
668 KMF_ALGORITHM_INDEX AlgId = KMF_ALGID_NONE;
669 KMF_DATA signature = { 0, NULL };
670 KMF_OID *oid;
671 KMF_POLICY_RECORD *policy;
672
673 KMF_ATTRIBUTE_TESTER required_attrs[] = {
674 {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)},
675 {KMF_DATA_ATTR, FALSE, sizeof (KMF_DATA), sizeof (KMF_DATA)},
676 {KMF_OUT_DATA_ATTR, FALSE, sizeof (KMF_DATA), sizeof (KMF_DATA)}
677 };
678 int num_req_attrs = sizeof (required_attrs) /
679 sizeof (KMF_ATTRIBUTE_TESTER);
680
681 if (handle == NULL)
682 return (KMF_ERR_BAD_PARAMETER);
683
684 CLEAR_ERROR(handle, ret);
685
686 ret = test_attributes(num_req_attrs, required_attrs,
687 0, NULL, numattr, attrlist);
688 if (ret != KMF_OK)
689 return (ret);
690
691 /* Get the signer cert and check its keyUsage. */
692 signer_cert = kmf_get_attr_ptr(KMF_SIGNER_CERT_DATA_ATTR, attrlist,
693 numattr);
694 sign_key_ptr = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist,
695 numattr);
696
697 if (signer_cert == NULL && sign_key_ptr == NULL)
698 return (KMF_ERR_BAD_PARAMETER);
699
700 /*
701 * If a signer cert was given, use it to find the private key
702 * to use for signing the data.
703 */
704 if (signer_cert != NULL) {
705 ret = check_key_usage(handle, signer_cert, KMF_KU_SIGN_DATA);
706
707 /*
708 * Signing generic data does not require the
709 * KeyUsage extension.
710 */
711 policy = handle->policy;
712 if (ret == KMF_ERR_EXTENSION_NOT_FOUND && policy->ku_bits == 0)
713 ret = KMF_OK;
714 if (ret != KMF_OK)
715 return (ret);
716
717 /*
718 * Find the private key from the signer certificate.
719 */
720 ret = setup_findprikey_attrlist(attrlist, numattr,
721 &new_attrlist, &new_numattr, &sign_key, signer_cert);
722 if (ret != KMF_OK) {
723 goto cleanup;
724 }
725
726 ret = kmf_find_prikey_by_cert(handle, new_numattr,
727 new_attrlist);
728 if (ret != KMF_OK) {
729 goto cleanup;
730 }
731 sign_key_ptr = &sign_key;
732 }
733
734 /* Get the tbs_data and signed_data attributes now */
735 tbs_data = kmf_get_attr_ptr(KMF_DATA_ATTR, attrlist, numattr);
736 if (tbs_data == NULL) {
737 ret = KMF_ERR_BAD_PARAMETER;
738 goto cleanup;
739 }
740
741 output = kmf_get_attr_ptr(KMF_OUT_DATA_ATTR, attrlist, numattr);
742 if (output == NULL) {
743 ret = KMF_ERR_BAD_PARAMETER;
744 goto cleanup;
745 }
746
747 /*
748 * Get the algorithm index attribute and its oid. If this attribute
749 * is not provided, then we use a default value.
750 */
751 oid = kmf_get_attr_ptr(KMF_OID_ATTR, attrlist, numattr);
752 if (oid == NULL) {
753 ret = kmf_get_attr(KMF_ALGORITHM_INDEX_ATTR, attrlist,
754 numattr, &AlgId, NULL);
755 /* If there was no Algorithm ID, use default based on key */
756 if (ret != KMF_OK)
757 oid = get_default_signoid(sign_key_ptr);
758 else
759 oid = x509_algid_to_algoid(AlgId);
760 }
761 if (sign_key_ptr->keyp == NULL) {
762 ret = KMF_ERR_BAD_PARAMETER;
763 goto cleanup;
764 }
765
766 /* Now call the plugin function to sign it */
767 plugin = FindPlugin(handle, sign_key_ptr->kstype);
768 if (plugin == NULL || plugin->funclist->SignData == NULL) {
769 ret = KMF_ERR_PLUGIN_NOTFOUND;
770 goto cleanup;
771 }
772
773 ret = plugin->funclist->SignData(handle, sign_key_ptr, oid, tbs_data,
774 output);
775 if (ret != KMF_OK)
776 goto cleanup;
777
778 /*
779 * For DSA, NSS returns an encoded signature. Decode the
780 * signature and expect a 40-byte DSA signature.
781 */
782 if (plugin->type == KMF_KEYSTORE_NSS &&
783 (IsEqualOid(oid, (KMF_OID *)&KMFOID_X9CM_DSAWithSHA1) ||
784 IsEqualOid(oid, (KMF_OID *)&KMFOID_SHA256WithDSA))) {
785 ret = DerDecodeDSASignature(output, &signature);
786 if (ret != KMF_OK)
787 goto cleanup;
788
789 output->Length = signature.Length;
790 (void) memcpy(output->Data, signature.Data, signature.Length);
791 }
792
793 cleanup:
794 if (new_attrlist != NULL)
795 free(new_attrlist);
796
797 if (signature.Data)
798 free(signature.Data);
799
800 if (signer_cert != NULL && sign_key_ptr != NULL)
801 kmf_free_kmf_key(handle, sign_key_ptr);
802
803 return (ret);
804 }
805
806 /*
807 * kmf_verify_data
808 *
809 * This routine will try to verify a block of data using
810 * either a public key or a certificate as the source
811 * of the verification (the key).
812 *
813 * The caller may provider either a KMF_KEY_HANDLE_ATTR or
814 * a KMF_SIGNER_CERT_DATA_ATTR (with a KMF_DATA record) to
815 * use for the key to the verification step. If a certificate
816 * is used and that certificate has the KeyUsage extension,
817 * the SIGN-DATA bit must be set. Also, if a certificate
818 * is used, the verification will be done in a specific
819 * keystore mechanism.
820 *
821 * If a KMF_KEY_HANDLE is given in the attribute list, the
822 * verification will occur in the framework itself using
823 * PKCS#11 C_Verify functions.
824 */
825 KMF_RETURN
kmf_verify_data(KMF_HANDLE_T handle,int num_args,KMF_ATTRIBUTE * attrlist)826 kmf_verify_data(KMF_HANDLE_T handle,
827 int num_args,
828 KMF_ATTRIBUTE *attrlist)
829 {
830 KMF_RETURN ret = KMF_OK;
831 KMF_PLUGIN *plugin;
832 KMF_KEYSTORE_TYPE kstype;
833 uint32_t len;
834 KMF_DATA derkey = { 0, NULL };
835 KMF_KEY_HANDLE *KMFKey;
836 KMF_ALGORITHM_INDEX sigAlg = KMF_ALGID_NONE;
837 KMF_DATA *indata;
838 KMF_DATA *insig;
839 KMF_DATA *signer_cert;
840 KMF_X509_SPKI spki;
841 KMF_POLICY_RECORD *policy;
842
843 KMF_ATTRIBUTE_TESTER required_attrs[] = {
844 {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)},
845 {KMF_DATA_ATTR, FALSE, sizeof (KMF_DATA),
846 sizeof (KMF_DATA)},
847 {KMF_IN_SIGN_ATTR, FALSE, sizeof (KMF_DATA),
848 sizeof (KMF_DATA)}
849 };
850
851 int num_req_attrs = sizeof (required_attrs) /
852 sizeof (KMF_ATTRIBUTE_TESTER);
853
854 if (handle == NULL)
855 return (KMF_ERR_BAD_PARAMETER);
856
857 CLEAR_ERROR(handle, ret);
858
859 ret = test_attributes(num_req_attrs, required_attrs,
860 0, NULL, num_args, attrlist);
861
862 if (ret != KMF_OK)
863 return (ret);
864
865 len = sizeof (kstype);
866 ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, num_args,
867 &kstype, &len);
868 if (ret != KMF_OK)
869 return (ret);
870
871 KMFKey = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, num_args);
872 signer_cert = kmf_get_attr_ptr(KMF_SIGNER_CERT_DATA_ATTR, attrlist,
873 num_args);
874 if (KMFKey == NULL && signer_cert == NULL) {
875 return (KMF_ERR_BAD_PARAMETER);
876 }
877
878 len = sizeof (sigAlg);
879 ret = kmf_get_attr(KMF_ALGORITHM_INDEX_ATTR, attrlist, num_args,
880 &sigAlg, &len);
881
882 /* We only need the algorithm index if we don't have a signer cert. */
883 if (ret != KMF_OK && signer_cert == NULL)
884 return (ret);
885
886 indata = kmf_get_attr_ptr(KMF_DATA_ATTR, attrlist, num_args);
887 if (indata == NULL)
888 return (KMF_ERR_BAD_PARAMETER);
889
890 insig = kmf_get_attr_ptr(KMF_IN_SIGN_ATTR, attrlist, num_args);
891 if (insig == NULL)
892 return (KMF_ERR_BAD_PARAMETER);
893
894 /* If the caller passed a signer cert instead of a key use it. */
895 if (signer_cert != NULL) {
896 KMF_X509_CERTIFICATE *SignerCert = NULL;
897
898 policy = handle->policy;
899 ret = check_key_usage(handle, signer_cert, KMF_KU_SIGN_DATA);
900 if (ret == KMF_ERR_EXTENSION_NOT_FOUND && policy->ku_bits == 0)
901 ret = KMF_OK;
902 if (ret != KMF_OK)
903 return (ret);
904
905 /* Decode the signer cert so we can get the SPKI data */
906 ret = DerDecodeSignedCertificate(signer_cert, &SignerCert);
907 if (ret != KMF_OK)
908 return (ret);
909
910 /* If no algorithm specified, use the certs signature alg */
911 if (sigAlg == KMF_ALGID_NONE)
912 sigAlg = x509_algoid_to_algid(CERT_ALG_OID(SignerCert));
913
914 if (sigAlg == KMF_ALGID_NONE) {
915 kmf_free_signed_cert(SignerCert);
916 free(SignerCert);
917 return (KMF_ERR_BAD_ALGORITHM);
918 }
919
920 /*
921 * Verify the data locally (i.e. using PKCS#11).
922 * The verify operation uses a public key and does not
923 * require access to a specific keystore. Save time
924 * (and code) by just using the frameworks implementation
925 * of the verify operation using crypto framework
926 * APIs.
927 */
928 ret = PKCS_VerifyData(handle, sigAlg,
929 &SignerCert->certificate.subjectPublicKeyInfo,
930 indata, insig);
931
932 kmf_free_signed_cert(SignerCert);
933 free(SignerCert);
934 } else {
935 /* Retrieve public key data from keystore */
936 plugin = FindPlugin(handle, kstype);
937 if (plugin != NULL &&
938 plugin->funclist->EncodePubkeyData != NULL) {
939 ret = plugin->funclist->EncodePubkeyData(handle,
940 KMFKey, &derkey);
941 } else {
942 return (KMF_ERR_PLUGIN_NOTFOUND);
943 }
944
945 ret = DerDecodeSPKI(&derkey, &spki);
946 if (ret == KMF_OK)
947 ret = PKCS_VerifyData(handle, sigAlg, &spki,
948 indata, insig);
949
950 if (derkey.Data != NULL)
951 free(derkey.Data);
952
953 kmf_free_algoid(&spki.algorithm);
954 kmf_free_data(&spki.subjectPublicKey);
955 }
956
957 return (ret);
958 }
959 /*
960 * Name: kmf_verify_cert
961 *
962 * Description:
963 * This function verifies that the a certificate was signed
964 * using a specific private key and that the certificate has not
965 * been altered since it was signed using that private key
966 * The public key used for verification may be given in the
967 * attribute list as a KMF_KEY_HANDLE or the caller may give
968 * just the signing certificate (as KMF_SIGNER_CERT_DATA_ATTR)
969 * from which the public key needed for verification can be
970 * derived.
971 *
972 * Parameters:
973 * handle(input) - opaque handle for KMF session
974 * numattr - number of attributes in the list
975 * attrlist - KMF_ATTRIBUTES
976 *
977 * Returns:
978 * A KMF_RETURN value indicating success or specifying a particular
979 * error condition. The value KMF_OK indicates success. All other
980 * values represent an error condition.
981 */
982 KMF_RETURN
kmf_verify_cert(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)983 kmf_verify_cert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
984 {
985 KMF_RETURN ret;
986 KMF_DATA derkey = { 0, NULL };
987 KMF_PLUGIN *plugin;
988 KMF_KEY_HANDLE *KMFKey;
989 KMF_DATA *CertToBeVerified;
990 KMF_DATA *SignerCert;
991 KMF_ATTRIBUTE_TESTER required_attrs[] = {
992 {KMF_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), sizeof (KMF_DATA)}
993 };
994
995 int num_req_attrs = sizeof (required_attrs) /
996 sizeof (KMF_ATTRIBUTE_TESTER);
997
998 CLEAR_ERROR(handle, ret);
999 if (ret != KMF_OK)
1000 return (ret);
1001
1002 ret = test_attributes(num_req_attrs, required_attrs,
1003 0, NULL, numattr, attrlist);
1004 if (ret != KMF_OK)
1005 return (ret);
1006
1007 KMFKey = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
1008 SignerCert = kmf_get_attr_ptr(KMF_SIGNER_CERT_DATA_ATTR, attrlist,
1009 numattr);
1010
1011 /*
1012 * Caller must provide at least a key handle or a cert to use
1013 * as the "key" for verification.
1014 */
1015 if (KMFKey == NULL && SignerCert == NULL)
1016 return (KMF_ERR_BAD_PARAMETER);
1017
1018 CertToBeVerified = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist,
1019 numattr);
1020 if (CertToBeVerified == NULL)
1021 return (KMF_ERR_BAD_PARAMETER);
1022
1023 if (SignerCert != NULL) {
1024 ret = verify_cert_with_cert(handle, CertToBeVerified,
1025 SignerCert);
1026 } else {
1027 /*
1028 * The keystore must extract the pubkey data because
1029 * the framework doesn't have access to the raw key bytes
1030 * that are needed to construct the DER encoded public
1031 * key information needed for the verify operation.
1032 */
1033 plugin = FindPlugin(handle, KMFKey->kstype);
1034 if (plugin != NULL && plugin->funclist->EncodePubkeyData !=
1035 NULL) {
1036 ret = plugin->funclist->EncodePubkeyData(handle,
1037 KMFKey, &derkey);
1038 } else {
1039 return (KMF_ERR_PLUGIN_NOTFOUND);
1040 }
1041
1042 if (ret == KMF_OK && derkey.Length > 0) {
1043 ret = verify_cert_with_key(handle, &derkey,
1044 CertToBeVerified);
1045
1046 if (derkey.Data != NULL)
1047 free(derkey.Data);
1048 }
1049 }
1050
1051 return (ret);
1052 }
1053
1054 /*
1055 * Name: kmf_encrypt
1056 *
1057 * Description:
1058 * Uses the public key from the cert to encrypt the plaintext
1059 * into the ciphertext.
1060 *
1061 * Parameters:
1062 * handle(input) - opaque handle for KMF session
1063 * cert(input) - pointer to a DER encoded certificate for encryption
1064 * by using its public key
1065 * plaintext(input) - pointer to the plaintext to be encrypted
1066 * ciphertext(output) - pointer to the ciphertext contains
1067 * encrypted data
1068 *
1069 * Returns:
1070 * A KMF_RETURN value indicating success or specifying a particular
1071 * error condition.
1072 * The value KMF_OK indicates success. All other values represent
1073 * an error condition.
1074 *
1075 */
1076 KMF_RETURN
kmf_encrypt(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)1077 kmf_encrypt(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
1078 {
1079 KMF_RETURN ret;
1080 KMF_X509_CERTIFICATE *x509cert = NULL;
1081 KMF_X509_SPKI *pubkey;
1082 KMF_OID *alg;
1083 KMF_ALGORITHM_INDEX algid;
1084 KMF_DATA *cert;
1085 KMF_DATA *plaintext;
1086 KMF_DATA *ciphertext;
1087 KMF_POLICY_RECORD *policy;
1088 KMF_ATTRIBUTE_TESTER required_attrs[] = {
1089 {KMF_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA),
1090 sizeof (KMF_DATA)},
1091 {KMF_PLAINTEXT_DATA_ATTR, FALSE, sizeof (KMF_DATA),
1092 sizeof (KMF_DATA)},
1093 {KMF_CIPHERTEXT_DATA_ATTR, FALSE, sizeof (KMF_DATA),
1094 sizeof (KMF_DATA)}
1095 };
1096
1097 int num_req_attrs = sizeof (required_attrs) /
1098 sizeof (KMF_ATTRIBUTE_TESTER);
1099
1100 CLEAR_ERROR(handle, ret);
1101 if (ret != KMF_OK)
1102 return (ret);
1103
1104 ret = test_attributes(num_req_attrs, required_attrs,
1105 0, NULL, numattr, attrlist);
1106 if (ret != KMF_OK)
1107 return (ret);
1108
1109 cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist,
1110 numattr);
1111 plaintext = kmf_get_attr_ptr(KMF_PLAINTEXT_DATA_ATTR, attrlist,
1112 numattr);
1113 ciphertext = kmf_get_attr_ptr(KMF_CIPHERTEXT_DATA_ATTR, attrlist,
1114 numattr);
1115
1116 if (cert == NULL || plaintext == NULL || ciphertext == NULL)
1117 return (KMF_ERR_BAD_PARAMETER);
1118
1119 /* check the keyUsage of the certificate */
1120 policy = handle->policy;
1121 ret = check_key_usage(handle, cert, KMF_KU_ENCRYPT_DATA);
1122 if (ret == KMF_ERR_EXTENSION_NOT_FOUND && policy->ku_bits == 0)
1123 ret = KMF_OK;
1124 if (ret != KMF_OK)
1125 return (ret);
1126
1127 /* Decode the cert so we can get the SPKI data */
1128 if ((ret = DerDecodeSignedCertificate(cert, &x509cert)) != KMF_OK)
1129 return (ret);
1130
1131 /* Get the public key info from the certificate */
1132 pubkey = &x509cert->certificate.subjectPublicKeyInfo;
1133
1134 /* Use the algorithm in SPKI to encrypt data */
1135 alg = &pubkey->algorithm.algorithm;
1136
1137 algid = x509_algoid_to_algid(alg);
1138
1139 /* [EC]DSA does not support encrypt */
1140 if (algid == KMF_ALGID_DSA ||
1141 algid == KMF_ALGID_SHA1WithDSA ||
1142 algid == KMF_ALGID_SHA256WithDSA ||
1143 algid == KMF_ALGID_SHA1WithECDSA ||
1144 algid == KMF_ALGID_SHA256WithECDSA ||
1145 algid == KMF_ALGID_SHA384WithECDSA ||
1146 algid == KMF_ALGID_SHA512WithECDSA ||
1147 algid == KMF_ALGID_NONE) {
1148 kmf_free_signed_cert(x509cert);
1149 free(x509cert);
1150 return (KMF_ERR_BAD_ALGORITHM);
1151 }
1152
1153 /*
1154 * Encrypt using the crypto framework (not the KMF plugin mechanism).
1155 */
1156 ret = PKCS_EncryptData(handle, algid, pubkey, plaintext, ciphertext);
1157
1158 kmf_free_signed_cert(x509cert);
1159 free(x509cert);
1160
1161 return (ret);
1162 }
1163
1164 /*
1165 * Name: kmf_decrypt
1166 *
1167 * Description:
1168 * Uses the private key associated with the cert to decrypt
1169 * the ciphertext into the plaintext.
1170 */
1171 KMF_RETURN
kmf_decrypt(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)1172 kmf_decrypt(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
1173 {
1174 KMF_RETURN ret;
1175 KMF_X509_CERTIFICATE *x509cert = NULL;
1176 KMF_X509_SPKI *spki_ptr;
1177 KMF_PLUGIN *plugin;
1178 KMF_ALGORITHM_INDEX AlgorithmId;
1179 KMF_ATTRIBUTE *new_attrlist = NULL;
1180 int new_numattr;
1181 KMF_DATA *cert = NULL;
1182 KMF_DATA *ciphertext = NULL;
1183 KMF_DATA *plaintext = NULL;
1184 KMF_KEY_HANDLE prikey;
1185 KMF_POLICY_RECORD *policy;
1186 KMF_ATTRIBUTE_TESTER required_attrs[] = {
1187 {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)},
1188 {KMF_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), sizeof (KMF_DATA)},
1189 {KMF_PLAINTEXT_DATA_ATTR, FALSE, sizeof (KMF_DATA),
1190 sizeof (KMF_DATA)},
1191 {KMF_CIPHERTEXT_DATA_ATTR, FALSE, sizeof (KMF_DATA),
1192 sizeof (KMF_DATA)},
1193 };
1194 int num_req_attrs = sizeof (required_attrs) /
1195 sizeof (KMF_ATTRIBUTE_TESTER);
1196
1197 if (handle == NULL)
1198 return (KMF_ERR_BAD_PARAMETER);
1199 CLEAR_ERROR(handle, ret);
1200
1201 ret = test_attributes(num_req_attrs, required_attrs,
1202 0, NULL, numattr, attrlist);
1203 if (ret != KMF_OK)
1204 return (ret);
1205
1206
1207 /* Get the cert and check its keyUsage */
1208 cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist,
1209 numattr);
1210 if (cert == NULL)
1211 return (KMF_ERR_BAD_PARAMETER);
1212
1213 /* check the keyUsage of the certificate */
1214 policy = handle->policy;
1215 ret = check_key_usage(handle, cert, KMF_KU_ENCRYPT_DATA);
1216 if (ret == KMF_ERR_EXTENSION_NOT_FOUND && policy->ku_bits == 0)
1217 ret = KMF_OK;
1218 if (ret != KMF_OK)
1219 return (ret);
1220
1221 /* Get the ciphertext and plaintext attributes */
1222 ciphertext = kmf_get_attr_ptr(KMF_CIPHERTEXT_DATA_ATTR, attrlist,
1223 numattr);
1224 if (ciphertext == NULL)
1225 return (KMF_ERR_BAD_PARAMETER);
1226
1227 plaintext = kmf_get_attr_ptr(KMF_PLAINTEXT_DATA_ATTR, attrlist,
1228 numattr);
1229 if (plaintext == NULL)
1230 return (KMF_ERR_BAD_PARAMETER);
1231
1232 /*
1233 * Retrieve the private key from the keystore based on
1234 * the certificate.
1235 */
1236 ret = setup_findprikey_attrlist(attrlist, numattr, &new_attrlist,
1237 &new_numattr, &prikey, cert);
1238 if (ret != KMF_OK)
1239 goto cleanup;
1240
1241 ret = kmf_find_prikey_by_cert(handle, new_numattr, new_attrlist);
1242 if (ret != KMF_OK)
1243 goto cleanup;
1244
1245 /* Decode the cert so we can get the alogorithm */
1246 ret = DerDecodeSignedCertificate(cert, &x509cert);
1247 if (ret != KMF_OK)
1248 goto cleanup;
1249
1250 spki_ptr = &x509cert->certificate.subjectPublicKeyInfo;
1251 AlgorithmId = x509_algoid_to_algid((KMF_OID *)
1252 &spki_ptr->algorithm.algorithm);
1253
1254 /* [EC]DSA does not support decrypt */
1255 if (AlgorithmId == KMF_ALGID_DSA ||
1256 AlgorithmId == KMF_ALGID_ECDSA) {
1257 ret = KMF_ERR_BAD_ALGORITHM;
1258 goto cleanup;
1259 }
1260
1261 plugin = FindPlugin(handle, prikey.kstype);
1262
1263 if (plugin != NULL && plugin->funclist->DecryptData != NULL) {
1264 ret = plugin->funclist->DecryptData(handle,
1265 &prikey, &spki_ptr->algorithm.algorithm,
1266 ciphertext, plaintext);
1267 } else {
1268 ret = KMF_ERR_PLUGIN_NOTFOUND;
1269 }
1270
1271 cleanup:
1272 if (new_attrlist != NULL)
1273 free(new_attrlist);
1274
1275 kmf_free_kmf_key(handle, &prikey);
1276 kmf_free_signed_cert(x509cert);
1277 free(x509cert);
1278
1279 return (ret);
1280 }
1281
1282 KMF_RETURN
kmf_store_cert(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)1283 kmf_store_cert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
1284 {
1285 KMF_PLUGIN *plugin;
1286 KMF_RETURN ret = KMF_OK;
1287 KMF_KEYSTORE_TYPE kstype;
1288
1289 KMF_ATTRIBUTE_TESTER required_attrs[] = {
1290 {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)},
1291 {KMF_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), sizeof (KMF_DATA)},
1292 };
1293
1294 int num_req_attrs = sizeof (required_attrs) /
1295 sizeof (KMF_ATTRIBUTE_TESTER);
1296
1297 if (handle == NULL)
1298 return (KMF_ERR_BAD_PARAMETER);
1299
1300 CLEAR_ERROR(handle, ret);
1301
1302 ret = test_attributes(num_req_attrs, required_attrs,
1303 0, NULL, numattr, attrlist);
1304 if (ret != KMF_OK)
1305 return (ret);
1306
1307 ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr,
1308 &kstype, NULL);
1309 if (ret != KMF_OK)
1310 return (ret);
1311
1312 plugin = FindPlugin(handle, kstype);
1313 if (plugin == NULL || plugin->funclist->StoreCert == NULL)
1314 return (KMF_ERR_PLUGIN_NOTFOUND);
1315
1316 return (plugin->funclist->StoreCert(handle, numattr, attrlist));
1317 }
1318
1319 KMF_RETURN
kmf_import_cert(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)1320 kmf_import_cert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
1321 {
1322 KMF_PLUGIN *plugin;
1323 KMF_RETURN ret = KMF_OK;
1324 KMF_KEYSTORE_TYPE kstype;
1325
1326 KMF_ATTRIBUTE_TESTER required_attrs[] = {
1327 {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)},
1328 {KMF_CERT_FILENAME_ATTR, TRUE, 1, 0},
1329 };
1330
1331 int num_req_attrs = sizeof (required_attrs) /
1332 sizeof (KMF_ATTRIBUTE_TESTER);
1333
1334 if (handle == NULL)
1335 return (KMF_ERR_BAD_PARAMETER);
1336
1337 CLEAR_ERROR(handle, ret);
1338
1339 ret = test_attributes(num_req_attrs, required_attrs, 0, NULL,
1340 numattr, attrlist);
1341 if (ret != KMF_OK)
1342 return (ret);
1343
1344 ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr,
1345 &kstype, NULL);
1346 if (ret != KMF_OK)
1347 return (ret);
1348
1349 plugin = FindPlugin(handle, kstype);
1350 if (plugin == NULL || plugin->funclist->ImportCert == NULL)
1351 return (KMF_ERR_PLUGIN_NOTFOUND);
1352
1353 return (plugin->funclist->ImportCert(handle, numattr, attrlist));
1354 }
1355
1356 KMF_RETURN
kmf_delete_cert_from_keystore(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)1357 kmf_delete_cert_from_keystore(KMF_HANDLE_T handle, int numattr,
1358 KMF_ATTRIBUTE *attrlist)
1359 {
1360 KMF_PLUGIN *plugin;
1361 KMF_RETURN ret = KMF_OK;
1362 KMF_KEYSTORE_TYPE kstype;
1363 KMF_ATTRIBUTE_TESTER required_attrs[] = {
1364 {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)}
1365 };
1366 int num_req_attrs = sizeof (required_attrs) /
1367 sizeof (KMF_ATTRIBUTE_TESTER);
1368
1369 if (handle == NULL)
1370 return (KMF_ERR_BAD_PARAMETER);
1371
1372 CLEAR_ERROR(handle, ret);
1373
1374 ret = test_attributes(num_req_attrs, required_attrs,
1375 0, NULL, numattr, attrlist);
1376 if (ret != KMF_OK)
1377 return (ret);
1378
1379 ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr,
1380 &kstype, NULL);
1381 if (ret != KMF_OK)
1382 return (ret);
1383
1384 plugin = FindPlugin(handle, kstype);
1385 if (plugin == NULL || plugin->funclist->DeleteCert == NULL)
1386 return (KMF_ERR_PLUGIN_NOTFOUND);
1387
1388 return (plugin->funclist->DeleteCert(handle, numattr, attrlist));
1389 }
1390
1391
1392 /*
1393 * This function gets the CRL URI entries from the certificate's Distribution
1394 * points extension, and downloads the CRL file. The function also returns
1395 * the URI string and the format of the CRL file. The caller should free
1396 * the space allocated for the returned URI string.
1397 */
1398 static KMF_RETURN
cert_get_crl(KMF_HANDLE_T handle,const KMF_DATA * cert,char * proxy,char * filename,char ** retn_uri,KMF_ENCODE_FORMAT * format)1399 cert_get_crl(KMF_HANDLE_T handle, const KMF_DATA *cert, char *proxy,
1400 char *filename, char **retn_uri, KMF_ENCODE_FORMAT *format)
1401 {
1402 KMF_RETURN ret = KMF_OK;
1403 KMF_X509EXT_CRLDISTPOINTS crl_dps;
1404 boolean_t done = B_FALSE;
1405 char uri[1024];
1406 char *proxyname = NULL;
1407 char *proxy_port_s = NULL;
1408 int proxy_port = 0;
1409 int i, j;
1410 char *path = NULL;
1411
1412 if (handle == NULL || cert == NULL || filename == NULL ||
1413 retn_uri == NULL || format == NULL)
1414 return (KMF_ERR_BAD_PARAMETER);
1415
1416 /* Get the proxy info */
1417 if (proxy != NULL) {
1418 proxyname = strtok(proxy, ":");
1419 proxy_port_s = strtok(NULL, "\0");
1420 if (proxy_port_s != NULL) {
1421 proxy_port = strtol(proxy_port_s, NULL, 0);
1422 } else {
1423 proxy_port = 8080; /* default */
1424 }
1425 }
1426
1427 /*
1428 * Get the CRL URI from the certificate's CRL Distribution
1429 * Points extension and download the CRL file. There maybe more than
1430 * one CRL URI entries in the DP extension, so we will continue
1431 * the process until a CRL file is sucessfully downloaded or we
1432 * are running out the CRL URI's.
1433 */
1434 ret = kmf_get_cert_crl_dist_pts((const KMF_DATA *)cert,
1435 &crl_dps);
1436 if (ret != KMF_OK)
1437 goto out;
1438
1439 for (i = 0; i < crl_dps.number; i++) {
1440 KMF_CRL_DIST_POINT *dp = &(crl_dps.dplist[i]);
1441 KMF_GENERALNAMES *fullname = &(dp->name.full_name);
1442 KMF_DATA *data;
1443
1444 if (done)
1445 break;
1446 for (j = 0; j < fullname->number; j++) {
1447 data = &(fullname->namelist[j].name);
1448 (void) memcpy(uri, data->Data, data->Length);
1449 uri[data->Length] = '\0';
1450 ret = kmf_download_crl(handle, uri, proxyname,
1451 proxy_port, 30, filename, format);
1452 if (ret == KMF_OK) {
1453 done = B_TRUE;
1454 path = malloc(data->Length + 1);
1455 if (path == NULL) {
1456 ret = KMF_ERR_MEMORY;
1457 goto out;
1458 }
1459 (void) strncpy(path, uri, data->Length);
1460 *retn_uri = path;
1461 break;
1462 }
1463 }
1464 }
1465
1466 out:
1467 kmf_free_crl_dist_pts(&crl_dps);
1468 return (ret);
1469 }
1470
1471 static KMF_RETURN
check_crl_validity(KMF_HANDLE_T handle,KMF_KEYSTORE_TYPE kstype,char * crlfilename,KMF_DATA * issuer_cert)1472 check_crl_validity(KMF_HANDLE_T handle, KMF_KEYSTORE_TYPE kstype,
1473 char *crlfilename, KMF_DATA *issuer_cert)
1474 {
1475 KMF_RETURN ret = KMF_OK;
1476 KMF_POLICY_RECORD *policy;
1477
1478 if (handle == NULL)
1479 return (KMF_ERR_BAD_PARAMETER);
1480
1481 policy = handle->policy;
1482
1483 /*
1484 * NSS CRL is not file based, and its signature
1485 * has been verified during CRL import.
1486 * We only check CRL validity for file-based CRLs,
1487 * NSS handles these checks internally.
1488 */
1489 if (kstype == KMF_KEYSTORE_NSS)
1490 return (KMF_OK);
1491
1492 /*
1493 * Check the CRL signature if needed.
1494 */
1495 if (!policy->validation_info.crl_info.ignore_crl_sign) {
1496 ret = kmf_verify_crl_file(handle, crlfilename,
1497 issuer_cert);
1498 if (ret != KMF_OK)
1499 return (ret);
1500 }
1501 /*
1502 * Check the CRL validity if needed.
1503 */
1504 if (!policy->validation_info.crl_info.ignore_crl_date) {
1505 ret = kmf_check_crl_date(handle, crlfilename);
1506 if (ret != KMF_OK)
1507 return (ret);
1508 }
1509
1510 return (ret);
1511 }
1512
1513 static KMF_RETURN
cert_crl_check(KMF_HANDLE_T handle,KMF_KEYSTORE_TYPE * kstype,KMF_DATA * user_cert,KMF_DATA * issuer_cert)1514 cert_crl_check(KMF_HANDLE_T handle, KMF_KEYSTORE_TYPE *kstype,
1515 KMF_DATA *user_cert, KMF_DATA *issuer_cert)
1516 {
1517 KMF_POLICY_RECORD *policy;
1518 KMF_RETURN ret = KMF_OK;
1519 KMF_ATTRIBUTE attrlist[16];
1520 int numattr = 0;
1521 int fd;
1522 boolean_t crlchk;
1523 char user_certfile[MAXPATHLEN];
1524 char crlfile_tmp[MAXPATHLEN];
1525 char *basefilename = NULL;
1526 char *dir = NULL;
1527 char *crlfilename = NULL;
1528 char *proxy = NULL;
1529 char *uri = NULL;
1530 KMF_ENCODE_FORMAT format;
1531
1532 if (handle == NULL || kstype == NULL || user_cert == NULL ||
1533 issuer_cert == NULL)
1534 return (KMF_ERR_BAD_PARAMETER);
1535
1536 if (!is_valid_keystore_type(*kstype))
1537 return (KMF_ERR_BAD_PARAMETER);
1538
1539 policy = handle->policy;
1540
1541 /*
1542 * If the get-crl-uri policy is TRUE, then download the CRL
1543 * file first. The newly downloaded file will be stored in the
1544 * NSS internal database for NSS keystore, and stored in a file for
1545 * the File-based CRL plugins (OpenSSL and PKCS11).
1546 *
1547 * For file-based plugins, if the get-crl-uri policy is FALSE,
1548 * then the caller should provide a CRL file in the policy.
1549 * Also, after this step is done, the "crlfilename" variable should
1550 * contain the proper CRL file to be used for the rest of CRL
1551 * validation process.
1552 */
1553 basefilename = policy->validation_info.crl_info.basefilename;
1554 dir = policy->validation_info.crl_info.directory;
1555 if (policy->validation_info.crl_info.get_crl_uri) {
1556 /*
1557 * Check to see if we already have this CRL.
1558 */
1559 if (basefilename == NULL)
1560 basefilename = basename(uri);
1561
1562 crlfilename = get_fullpath(dir == NULL ? "./" : dir,
1563 basefilename);
1564 if (crlfilename == NULL) {
1565 ret = KMF_ERR_BAD_CRLFILE;
1566 goto cleanup;
1567 }
1568
1569 /*
1570 * If this file already exists and is valid, we don't need to
1571 * download a new one.
1572 */
1573 if ((fd = open(crlfilename, O_RDONLY)) != -1) {
1574 (void) close(fd);
1575 if ((ret = check_crl_validity(handle, *kstype,
1576 crlfilename, issuer_cert)) == KMF_OK) {
1577 goto checkcrl;
1578 }
1579 }
1580
1581 /*
1582 * Create a temporary file to hold the new CRL file initially.
1583 */
1584 (void) strlcpy(crlfile_tmp, CRLFILE_TEMPNAME,
1585 sizeof (crlfile_tmp));
1586 if (mkstemp(crlfile_tmp) == -1) {
1587 ret = KMF_ERR_INTERNAL;
1588 goto cleanup;
1589 }
1590
1591 /*
1592 * Get the URI entry from the certificate's CRL distribution
1593 * points extension and download the CRL file.
1594 */
1595 proxy = policy->validation_info.crl_info.proxy;
1596 ret = cert_get_crl(handle, user_cert, proxy, crlfile_tmp,
1597 &uri, &format);
1598 if (ret != KMF_OK) {
1599 (void) unlink(crlfile_tmp);
1600 goto cleanup;
1601 }
1602 /*
1603 * If we just downloaded one, make sure it is OK.
1604 */
1605 if ((ret = check_crl_validity(handle, *kstype, crlfile_tmp,
1606 issuer_cert)) != KMF_OK)
1607 return (ret);
1608
1609 /* Cache the CRL file. */
1610 if (*kstype == KMF_KEYSTORE_NSS) {
1611 /*
1612 * For NSS keystore, import this CRL file into th
1613 * internal database.
1614 */
1615 numattr = 0;
1616 kmf_set_attr_at_index(attrlist, numattr,
1617 KMF_KEYSTORE_TYPE_ATTR, kstype, sizeof (kstype));
1618 numattr++;
1619
1620 kmf_set_attr_at_index(attrlist, numattr,
1621 KMF_CRL_FILENAME_ATTR, crlfile_tmp,
1622 strlen(crlfile_tmp));
1623 numattr++;
1624
1625 crlchk = B_FALSE;
1626 kmf_set_attr_at_index(attrlist, numattr,
1627 KMF_CRL_CHECK_ATTR, &crlchk, sizeof (boolean_t));
1628 numattr++;
1629
1630 ret = kmf_import_crl(handle, numattr, attrlist);
1631 (void) unlink(crlfile_tmp);
1632 if (ret != KMF_OK)
1633 goto cleanup;
1634 } else {
1635 if (rename(crlfile_tmp, crlfilename) == -1) {
1636 (void) unlink(crlfile_tmp);
1637 ret = KMF_ERR_WRITE_FILE;
1638 goto cleanup;
1639 }
1640 }
1641 } else {
1642 /*
1643 * If the get_crl_uri policy is FALSE, for File-based CRL
1644 * plugins, get the input CRL file from the policy.
1645 */
1646 if (*kstype != KMF_KEYSTORE_NSS) {
1647 if (basefilename == NULL) {
1648 ret = KMF_ERR_BAD_PARAMETER;
1649 goto cleanup;
1650 }
1651
1652 crlfilename = get_fullpath(dir == NULL ? "./" : dir,
1653 basefilename);
1654 if (crlfilename == NULL) {
1655 ret = KMF_ERR_BAD_CRLFILE;
1656 goto cleanup;
1657 }
1658 /*
1659 * Make sure this CRL is still valid.
1660 */
1661 if ((ret = check_crl_validity(handle, *kstype,
1662 crlfilename, issuer_cert)) != KMF_OK)
1663 return (ret);
1664 }
1665 }
1666
1667 checkcrl:
1668 /*
1669 * Check the CRL revocation for the certificate.
1670 */
1671 numattr = 0;
1672
1673 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
1674 kstype, sizeof (kstype));
1675 numattr++;
1676
1677 switch (*kstype) {
1678 case KMF_KEYSTORE_NSS:
1679 kmf_set_attr_at_index(attrlist, numattr,
1680 KMF_CERT_DATA_ATTR, user_cert, sizeof (KMF_DATA));
1681 numattr++;
1682 break;
1683 case KMF_KEYSTORE_PK11TOKEN:
1684 case KMF_KEYSTORE_OPENSSL:
1685 /*
1686 * Create temporary file to hold the user certificate.
1687 */
1688 (void) strlcpy(user_certfile, CERTFILE_TEMPNAME,
1689 sizeof (user_certfile));
1690 if (mkstemp(user_certfile) == -1) {
1691 ret = KMF_ERR_INTERNAL;
1692 goto cleanup;
1693 }
1694
1695 ret = kmf_create_cert_file(user_cert, KMF_FORMAT_ASN1,
1696 user_certfile);
1697 if (ret != KMF_OK) {
1698 goto cleanup;
1699 }
1700
1701 kmf_set_attr_at_index(attrlist, numattr,
1702 KMF_CERT_FILENAME_ATTR,
1703 user_certfile, strlen(user_certfile));
1704 numattr++;
1705
1706 kmf_set_attr_at_index(attrlist, numattr,
1707 KMF_CRL_FILENAME_ATTR,
1708 crlfilename, strlen(crlfilename));
1709 numattr++;
1710 break;
1711 default:
1712 ret = KMF_ERR_PLUGIN_NOTFOUND;
1713 goto cleanup;
1714 }
1715
1716 ret = kmf_find_cert_in_crl(handle, numattr, attrlist);
1717 if (ret == KMF_ERR_NOT_REVOKED) {
1718 ret = KMF_OK;
1719 }
1720
1721 cleanup:
1722 (void) unlink(user_certfile);
1723
1724 if (crlfilename != NULL)
1725 free(crlfilename);
1726
1727 if (uri != NULL)
1728 free(uri);
1729
1730 return (ret);
1731 }
1732
1733 static KMF_RETURN
cert_ocsp_check(KMF_HANDLE_T handle,KMF_KEYSTORE_TYPE * kstype,KMF_DATA * user_cert,KMF_DATA * issuer_cert,KMF_DATA * response,char * slotlabel,char * dirpath)1734 cert_ocsp_check(KMF_HANDLE_T handle, KMF_KEYSTORE_TYPE *kstype,
1735 KMF_DATA *user_cert, KMF_DATA *issuer_cert, KMF_DATA *response,
1736 char *slotlabel, char *dirpath)
1737 {
1738 KMF_RETURN ret = KMF_OK;
1739 KMF_POLICY_RECORD *policy;
1740 KMF_DATA *new_response = NULL;
1741 boolean_t ignore_response_sign = B_FALSE;
1742 uint32_t ltime = 0;
1743 KMF_DATA *signer_cert = NULL;
1744 KMF_BIGINT sernum = { NULL, 0 };
1745 int response_status;
1746 int reason;
1747 int cert_status;
1748 KMF_ATTRIBUTE attrlist[32];
1749 int numattr;
1750
1751 if (handle == NULL || kstype == NULL || user_cert == NULL ||
1752 issuer_cert == NULL)
1753 return (KMF_ERR_BAD_PARAMETER);
1754
1755 policy = handle->policy;
1756
1757 /*
1758 * Get the response lifetime from policy.
1759 */
1760 if (policy->VAL_OCSP_BASIC.response_lifetime != NULL &&
1761 (str2lifetime(policy->VAL_OCSP_BASIC.response_lifetime, <ime)
1762 < 0))
1763 return (KMF_ERR_OCSP_RESPONSE_LIFETIME);
1764
1765 /*
1766 * Get the ignore_response_sign policy.
1767 *
1768 * If ignore_response_sign is FALSE, we need to verify the response.
1769 * Find the OCSP Responder certificate if it is specified in the OCSP
1770 * policy.
1771 */
1772 ignore_response_sign = policy->VAL_OCSP_BASIC.ignore_response_sign;
1773
1774 if (ignore_response_sign == B_FALSE &&
1775 policy->VAL_OCSP.has_resp_cert == B_TRUE) {
1776 char *signer_name;
1777 KMF_X509_DER_CERT signer_retrcert;
1778 uchar_t *bytes = NULL;
1779 size_t bytelen;
1780 uint32_t num = 0;
1781 KMF_ATTRIBUTE fc_attrlist[16];
1782 int fc_numattr = 0;
1783 char *dir = "./";
1784
1785 if (policy->VAL_OCSP_RESP_CERT.name == NULL ||
1786 policy->VAL_OCSP_RESP_CERT.serial == NULL)
1787 return (KMF_ERR_POLICY_NOT_FOUND);
1788
1789 signer_cert = malloc(sizeof (KMF_DATA));
1790 if (signer_cert == NULL) {
1791 ret = KMF_ERR_MEMORY;
1792 goto out;
1793 }
1794 (void) memset(signer_cert, 0, sizeof (KMF_DATA));
1795
1796 signer_name = policy->VAL_OCSP_RESP_CERT.name;
1797 ret = kmf_hexstr_to_bytes(
1798 (uchar_t *)policy->VAL_OCSP_RESP_CERT.serial,
1799 &bytes, &bytelen);
1800 if (ret != KMF_OK || bytes == NULL) {
1801 ret = KMF_ERR_OCSP_POLICY;
1802 goto out;
1803 }
1804 sernum.val = bytes;
1805 sernum.len = bytelen;
1806
1807 kmf_set_attr_at_index(fc_attrlist, fc_numattr,
1808 KMF_KEYSTORE_TYPE_ATTR, kstype,
1809 sizeof (KMF_KEYSTORE_TYPE));
1810 fc_numattr++;
1811
1812 kmf_set_attr_at_index(fc_attrlist, fc_numattr,
1813 KMF_SUBJECT_NAME_ATTR, signer_name, strlen(signer_name));
1814 fc_numattr++;
1815
1816 kmf_set_attr_at_index(fc_attrlist, fc_numattr, KMF_BIGINT_ATTR,
1817 &sernum, sizeof (KMF_BIGINT));
1818 fc_numattr++;
1819
1820 if (*kstype == KMF_KEYSTORE_NSS && slotlabel != NULL) {
1821 kmf_set_attr_at_index(fc_attrlist, fc_numattr,
1822 KMF_TOKEN_LABEL_ATTR, slotlabel,
1823 strlen(slotlabel));
1824 fc_numattr++;
1825 }
1826
1827 if (*kstype == KMF_KEYSTORE_OPENSSL) {
1828 if (dirpath == NULL) {
1829 kmf_set_attr_at_index(fc_attrlist, fc_numattr,
1830 KMF_DIRPATH_ATTR, dir, strlen(dir));
1831 fc_numattr++;
1832 } else {
1833 kmf_set_attr_at_index(fc_attrlist, fc_numattr,
1834 KMF_DIRPATH_ATTR, dirpath,
1835 strlen(dirpath));
1836 fc_numattr++;
1837 }
1838 }
1839
1840 num = 0;
1841 kmf_set_attr_at_index(fc_attrlist, fc_numattr,
1842 KMF_COUNT_ATTR, &num, sizeof (uint32_t));
1843 fc_numattr++;
1844
1845 ret = kmf_find_cert(handle, fc_numattr, fc_attrlist);
1846 if (ret != KMF_OK || num != 1) {
1847 if (num == 0)
1848 ret = KMF_ERR_CERT_NOT_FOUND;
1849 if (num > 0)
1850 ret = KMF_ERR_CERT_MULTIPLE_FOUND;
1851 goto out;
1852 }
1853
1854 (void) memset(&signer_retrcert, 0, sizeof (KMF_X509_DER_CERT));
1855 kmf_set_attr_at_index(fc_attrlist, fc_numattr,
1856 KMF_X509_DER_CERT_ATTR, &signer_retrcert,
1857 sizeof (KMF_X509_DER_CERT));
1858 fc_numattr++;
1859
1860 ret = kmf_find_cert(handle, fc_numattr, fc_attrlist);
1861 if (ret == KMF_OK) {
1862 signer_cert->Length =
1863 signer_retrcert.certificate.Length;
1864 signer_cert->Data = signer_retrcert.certificate.Data;
1865 } else {
1866 goto out;
1867 }
1868 }
1869
1870 /*
1871 * If the caller provides an OCSP response, we will use it directly.
1872 * Otherwise, we will try to fetch an OCSP response for the given
1873 * certificate now.
1874 */
1875 if (response == NULL) {
1876 new_response = (KMF_DATA *) malloc(sizeof (KMF_DATA));
1877 if (new_response == NULL) {
1878 ret = KMF_ERR_MEMORY;
1879 goto out;
1880 }
1881 new_response->Data = NULL;
1882 new_response->Length = 0;
1883
1884 ret = kmf_get_ocsp_for_cert(handle, user_cert, issuer_cert,
1885 new_response);
1886 if (ret != KMF_OK)
1887 goto out;
1888 }
1889
1890 /*
1891 * Process the OCSP response and retrieve the certificate status.
1892 */
1893 numattr = 0;
1894 kmf_set_attr_at_index(attrlist, numattr, KMF_ISSUER_CERT_DATA_ATTR,
1895 issuer_cert, sizeof (KMF_DATA));
1896 numattr++;
1897
1898 kmf_set_attr_at_index(attrlist, numattr, KMF_USER_CERT_DATA_ATTR,
1899 user_cert, sizeof (KMF_DATA));
1900 numattr++;
1901
1902 if (signer_cert != NULL) {
1903 kmf_set_attr_at_index(attrlist, numattr,
1904 KMF_SIGNER_CERT_DATA_ATTR, user_cert, sizeof (KMF_DATA));
1905 numattr++;
1906 }
1907
1908 kmf_set_attr_at_index(attrlist, numattr, KMF_OCSP_RESPONSE_DATA_ATTR,
1909 response == NULL ? new_response : response, sizeof (KMF_DATA));
1910 numattr++;
1911
1912 kmf_set_attr_at_index(attrlist, numattr, KMF_RESPONSE_LIFETIME_ATTR,
1913 <ime, sizeof (uint32_t));
1914 numattr++;
1915
1916 kmf_set_attr_at_index(attrlist, numattr,
1917 KMF_IGNORE_RESPONSE_SIGN_ATTR, &ignore_response_sign,
1918 sizeof (boolean_t));
1919 numattr++;
1920
1921 kmf_set_attr_at_index(attrlist, numattr,
1922 KMF_OCSP_RESPONSE_STATUS_ATTR, &response_status, sizeof (int));
1923 numattr++;
1924
1925 kmf_set_attr_at_index(attrlist, numattr,
1926 KMF_OCSP_RESPONSE_REASON_ATTR, &reason, sizeof (int));
1927 numattr++;
1928
1929 kmf_set_attr_at_index(attrlist, numattr,
1930 KMF_OCSP_RESPONSE_CERT_STATUS_ATTR, &cert_status, sizeof (int));
1931 numattr++;
1932
1933 ret = kmf_get_ocsp_status_for_cert(handle, numattr, attrlist);
1934 if (ret == KMF_OK) {
1935 switch (cert_status) {
1936 case OCSP_GOOD:
1937 break;
1938 case OCSP_UNKNOWN:
1939 ret = KMF_ERR_OCSP_UNKNOWN_CERT;
1940 break;
1941 case OCSP_REVOKED:
1942 ret = KMF_ERR_OCSP_REVOKED;
1943 break;
1944 }
1945 }
1946
1947 out:
1948 if (new_response) {
1949 kmf_free_data(new_response);
1950 free(new_response);
1951 }
1952
1953 if (signer_cert) {
1954 kmf_free_data(signer_cert);
1955 free(signer_cert);
1956 }
1957
1958 if (sernum.val != NULL)
1959 free(sernum.val);
1960
1961 return (ret);
1962 }
1963
1964 static KMF_RETURN
cert_ku_check(KMF_HANDLE_T handle,KMF_DATA * cert)1965 cert_ku_check(KMF_HANDLE_T handle, KMF_DATA *cert)
1966 {
1967 KMF_POLICY_RECORD *policy;
1968 KMF_X509EXT_KEY_USAGE keyusage;
1969 KMF_RETURN ret = KMF_OK;
1970 KMF_X509EXT_BASICCONSTRAINTS constraint;
1971 KMF_BOOL critical = B_FALSE;
1972
1973 if (handle == NULL || cert == NULL)
1974 return (KMF_ERR_BAD_PARAMETER);
1975
1976 policy = handle->policy;
1977 (void) memset(&keyusage, 0, sizeof (keyusage));
1978 ret = kmf_get_cert_ku(cert, &keyusage);
1979
1980 if (ret == KMF_ERR_EXTENSION_NOT_FOUND) {
1981 if (policy->ku_bits) {
1982 /* keyusage is not set in cert but is set in policy */
1983 return (KMF_ERR_KEYUSAGE);
1984 } else {
1985 /* no keyusage set in both cert and policy */
1986 return (KMF_OK);
1987 }
1988 }
1989
1990 if (ret != KMF_OK) {
1991 /* real error */
1992 return (ret);
1993 }
1994
1995 /*
1996 * If KeyCertSign is set, then constraints.cA must be TRUE and
1997 * marked critical.
1998 */
1999 if ((keyusage.KeyUsageBits & KMF_keyCertSign)) {
2000 (void) memset(&constraint, 0, sizeof (constraint));
2001 ret = kmf_get_cert_basic_constraint(cert,
2002 &critical, &constraint);
2003
2004 if (ret != KMF_OK) {
2005 /* real error */
2006 return (ret);
2007 }
2008 if (!constraint.cA || !critical)
2009 return (KMF_ERR_KEYUSAGE);
2010 }
2011
2012 /*
2013 * Rule: if the KU bit is set in policy, the corresponding KU bit
2014 * must be set in the certificate (but not vice versa).
2015 */
2016 if ((policy->ku_bits & keyusage.KeyUsageBits) == policy->ku_bits) {
2017 return (KMF_OK);
2018 } else {
2019 return (KMF_ERR_KEYUSAGE);
2020 }
2021
2022 }
2023
2024 static KMF_RETURN
cert_eku_check(KMF_HANDLE_T handle,KMF_DATA * cert)2025 cert_eku_check(KMF_HANDLE_T handle, KMF_DATA *cert)
2026 {
2027 KMF_POLICY_RECORD *policy;
2028 KMF_RETURN ret = KMF_OK;
2029 KMF_X509EXT_EKU eku;
2030 uint16_t cert_eku = 0, policy_eku = 0;
2031 int i;
2032
2033 if (handle == NULL || cert == NULL)
2034 return (KMF_ERR_BAD_PARAMETER);
2035 policy = handle->policy;
2036
2037 /*
2038 * If the policy does not have any EKU, then there is
2039 * nothing further to check.
2040 */
2041 if (policy->eku_set.eku_count == 0)
2042 return (KMF_OK);
2043
2044 ret = kmf_get_cert_eku(cert, &eku);
2045 if ((ret != KMF_ERR_EXTENSION_NOT_FOUND) && (ret != KMF_OK)) {
2046 /* real error */
2047 return (ret);
2048 }
2049
2050 if (ret == KMF_ERR_EXTENSION_NOT_FOUND) {
2051 cert_eku = 0;
2052 } else {
2053 /*
2054 * Build the EKU bitmap based on the certificate
2055 */
2056 for (i = 0; i < eku.nEKUs; i++) {
2057 if (IsEqualOid(&eku.keyPurposeIdList[i],
2058 (KMF_OID *)&KMFOID_PKIX_KP_ServerAuth)) {
2059 cert_eku |= KMF_EKU_SERVERAUTH;
2060 } else if (IsEqualOid(&eku.keyPurposeIdList[i],
2061 (KMF_OID *)&KMFOID_PKIX_KP_ClientAuth)) {
2062 cert_eku |= KMF_EKU_CLIENTAUTH;
2063 } else if (IsEqualOid(&eku.keyPurposeIdList[i],
2064 (KMF_OID *)&KMFOID_PKIX_KP_CodeSigning)) {
2065 cert_eku |= KMF_EKU_CODESIGNING;
2066 } else if (IsEqualOid(&eku.keyPurposeIdList[i],
2067 (KMF_OID *)&KMFOID_PKIX_KP_EmailProtection)) {
2068 cert_eku |= KMF_EKU_EMAIL;
2069 } else if (IsEqualOid(&eku.keyPurposeIdList[i],
2070 (KMF_OID *)&KMFOID_PKIX_KP_TimeStamping)) {
2071 cert_eku |= KMF_EKU_TIMESTAMP;
2072 } else if (IsEqualOid(&eku.keyPurposeIdList[i],
2073 (KMF_OID *)&KMFOID_PKIX_KP_OCSPSigning)) {
2074 cert_eku |= KMF_EKU_OCSPSIGNING;
2075 } else if (!policy->ignore_unknown_ekus) {
2076 return (KMF_ERR_KEYUSAGE);
2077 }
2078 } /* for */
2079 }
2080
2081
2082 /*
2083 * Build the EKU bitmap based on the policy
2084 */
2085 for (i = 0; i < policy->eku_set.eku_count; i++) {
2086 if (IsEqualOid(&policy->eku_set.ekulist[i],
2087 (KMF_OID *)&KMFOID_PKIX_KP_ServerAuth)) {
2088 policy_eku |= KMF_EKU_SERVERAUTH;
2089 } else if (IsEqualOid(&policy->eku_set.ekulist[i],
2090 (KMF_OID *)&KMFOID_PKIX_KP_ClientAuth)) {
2091 policy_eku |= KMF_EKU_CLIENTAUTH;
2092 } else if (IsEqualOid(&policy->eku_set.ekulist[i],
2093 (KMF_OID *)&KMFOID_PKIX_KP_CodeSigning)) {
2094 policy_eku |= KMF_EKU_CODESIGNING;
2095 } else if (IsEqualOid(&policy->eku_set.ekulist[i],
2096 (KMF_OID *)&KMFOID_PKIX_KP_EmailProtection)) {
2097 policy_eku |= KMF_EKU_EMAIL;
2098 } else if (IsEqualOid(&policy->eku_set.ekulist[i],
2099 (KMF_OID *)&KMFOID_PKIX_KP_TimeStamping)) {
2100 policy_eku |= KMF_EKU_TIMESTAMP;
2101 } else if (IsEqualOid(&policy->eku_set.ekulist[i],
2102 (KMF_OID *)&KMFOID_PKIX_KP_OCSPSigning)) {
2103 policy_eku |= KMF_EKU_OCSPSIGNING;
2104 } else if (!policy->ignore_unknown_ekus) {
2105 return (KMF_ERR_KEYUSAGE);
2106 }
2107 } /* for */
2108
2109 /*
2110 * Rule: if the EKU OID is set in policy, the corresponding EKU OID
2111 * must be set in the certificate (but not vice versa).
2112 */
2113 if ((policy_eku & cert_eku) == policy_eku) {
2114 return (KMF_OK);
2115 } else {
2116 return (KMF_ERR_KEYUSAGE);
2117 }
2118 }
2119
2120 static KMF_RETURN
find_issuer_cert(KMF_HANDLE_T handle,KMF_KEYSTORE_TYPE * kstype,char * user_issuer,KMF_DATA * issuer_cert,char * slotlabel,char * dirpath)2121 find_issuer_cert(KMF_HANDLE_T handle, KMF_KEYSTORE_TYPE *kstype,
2122 char *user_issuer, KMF_DATA *issuer_cert,
2123 char *slotlabel, char *dirpath)
2124 {
2125 KMF_RETURN ret = KMF_OK;
2126 KMF_X509_DER_CERT *certlist = NULL;
2127 uint32_t i, num = 0;
2128 time_t t_notbefore;
2129 time_t t_notafter;
2130 time_t latest;
2131 KMF_DATA tmp_cert = { 0, NULL };
2132 KMF_ATTRIBUTE fc_attrlist[16];
2133 int fc_numattr = 0;
2134 char *dir = "./";
2135
2136 if (handle == NULL || kstype == NULL || user_issuer == NULL ||
2137 issuer_cert == NULL)
2138 return (KMF_ERR_BAD_PARAMETER);
2139
2140 if (!is_valid_keystore_type(*kstype))
2141 return (KMF_ERR_BAD_PARAMETER);
2142
2143 kmf_set_attr_at_index(fc_attrlist, fc_numattr, KMF_KEYSTORE_TYPE_ATTR,
2144 kstype, sizeof (KMF_KEYSTORE_TYPE));
2145 fc_numattr++;
2146
2147 kmf_set_attr_at_index(fc_attrlist, fc_numattr, KMF_SUBJECT_NAME_ATTR,
2148 user_issuer, strlen(user_issuer));
2149 fc_numattr++;
2150
2151 if (*kstype == KMF_KEYSTORE_NSS && slotlabel != NULL) {
2152 kmf_set_attr_at_index(fc_attrlist, fc_numattr,
2153 KMF_TOKEN_LABEL_ATTR, slotlabel, strlen(slotlabel));
2154 fc_numattr++;
2155 }
2156
2157 if (*kstype == KMF_KEYSTORE_OPENSSL) {
2158 if (dirpath == NULL) {
2159 kmf_set_attr_at_index(fc_attrlist, fc_numattr,
2160 KMF_DIRPATH_ATTR, dir, strlen(dir));
2161 fc_numattr++;
2162 } else {
2163 kmf_set_attr_at_index(fc_attrlist, fc_numattr,
2164 KMF_DIRPATH_ATTR, dirpath, strlen(dirpath));
2165 fc_numattr++;
2166 }
2167 }
2168
2169 num = 0;
2170 kmf_set_attr_at_index(fc_attrlist, fc_numattr,
2171 KMF_COUNT_ATTR, &num, sizeof (uint32_t));
2172 fc_numattr++;
2173
2174 ret = kmf_find_cert(handle, fc_numattr, fc_attrlist);
2175
2176 if (ret == KMF_OK && num > 0) {
2177 certlist = (KMF_X509_DER_CERT *)malloc(num *
2178 sizeof (KMF_X509_DER_CERT));
2179
2180 if (certlist == NULL) {
2181 ret = KMF_ERR_MEMORY;
2182 goto out;
2183 }
2184
2185 kmf_set_attr_at_index(fc_attrlist, fc_numattr,
2186 KMF_X509_DER_CERT_ATTR, certlist,
2187 sizeof (KMF_X509_DER_CERT));
2188 fc_numattr++;
2189
2190 ret = kmf_find_cert(handle, fc_numattr, fc_attrlist);
2191 if (ret != KMF_OK) {
2192 free(certlist);
2193 certlist = NULL;
2194 goto out;
2195 }
2196 } else {
2197 goto out;
2198 }
2199
2200 if (num == 1) {
2201 /* only one issuer cert is found */
2202 tmp_cert.Length = certlist[0].certificate.Length;
2203 tmp_cert.Data = certlist[0].certificate.Data;
2204 } else {
2205 /*
2206 * More than one issuer certs are found. We will
2207 * pick the latest one.
2208 */
2209 latest = 0;
2210 for (i = 0; i < num; i++) {
2211 ret = kmf_get_cert_validity(&certlist[i].certificate,
2212 &t_notbefore, &t_notafter);
2213 if (ret != KMF_OK) {
2214 ret = KMF_ERR_VALIDITY_PERIOD;
2215 goto out;
2216 }
2217
2218 if (t_notbefore > latest) {
2219 tmp_cert.Length =
2220 certlist[i].certificate.Length;
2221 tmp_cert.Data =
2222 certlist[i].certificate.Data;
2223 latest = t_notbefore;
2224 }
2225
2226 }
2227 }
2228
2229 issuer_cert->Length = tmp_cert.Length;
2230 issuer_cert->Data = malloc(tmp_cert.Length);
2231 if (issuer_cert->Data == NULL) {
2232 ret = KMF_ERR_MEMORY;
2233 goto out;
2234 }
2235 (void) memcpy(issuer_cert->Data, tmp_cert.Data,
2236 tmp_cert.Length);
2237
2238 out:
2239 if (certlist != NULL) {
2240 for (i = 0; i < num; i++)
2241 kmf_free_kmf_cert(handle, &certlist[i]);
2242 free(certlist);
2243 }
2244
2245 return (ret);
2246
2247 }
2248
2249 static KMF_RETURN
find_ta_cert(KMF_HANDLE_T handle,KMF_KEYSTORE_TYPE * kstype,KMF_DATA * ta_cert,KMF_X509_NAME * user_issuerDN,char * slotlabel,char * dirpath)2250 find_ta_cert(KMF_HANDLE_T handle, KMF_KEYSTORE_TYPE *kstype,
2251 KMF_DATA *ta_cert, KMF_X509_NAME *user_issuerDN,
2252 char *slotlabel, char *dirpath)
2253 {
2254 KMF_POLICY_RECORD *policy;
2255 KMF_RETURN ret = KMF_OK;
2256 uint32_t num = 0;
2257 char *ta_name;
2258 KMF_BIGINT serial = { NULL, 0 };
2259 uchar_t *bytes = NULL;
2260 size_t bytelen;
2261 KMF_X509_DER_CERT ta_retrCert;
2262 char *ta_subject = NULL;
2263 KMF_X509_NAME ta_subjectDN;
2264 KMF_ATTRIBUTE fc_attrlist[16];
2265 int fc_numattr = 0;
2266 char *dir = "./";
2267
2268 if (handle == NULL || kstype == NULL || ta_cert == NULL ||
2269 user_issuerDN == NULL)
2270 return (KMF_ERR_BAD_PARAMETER);
2271
2272 if (!is_valid_keystore_type(*kstype))
2273 return (KMF_ERR_BAD_PARAMETER);
2274
2275 /* Get the TA name and serial number from the policy */
2276 policy = handle->policy;
2277 ta_name = policy->ta_name;
2278
2279 /*
2280 * Use name and serial from policy.
2281 */
2282 ret = kmf_hexstr_to_bytes((uchar_t *)policy->ta_serial,
2283 &bytes, &bytelen);
2284 if (ret != KMF_OK || bytes == NULL) {
2285 ret = KMF_ERR_TA_POLICY;
2286 goto out;
2287 }
2288 serial.val = bytes;
2289 serial.len = bytelen;
2290
2291 /* set up fc_attrlist for kmf_find_cert */
2292 kmf_set_attr_at_index(fc_attrlist,
2293 fc_numattr++, KMF_BIGINT_ATTR,
2294 &serial, sizeof (KMF_BIGINT));
2295
2296 kmf_set_attr_at_index(fc_attrlist,
2297 fc_numattr++, KMF_SUBJECT_NAME_ATTR,
2298 ta_name, strlen(ta_name));
2299
2300 kmf_set_attr_at_index(fc_attrlist, fc_numattr++, KMF_KEYSTORE_TYPE_ATTR,
2301 kstype, sizeof (KMF_KEYSTORE_TYPE));
2302
2303 if (*kstype == KMF_KEYSTORE_NSS && slotlabel != NULL) {
2304 kmf_set_attr_at_index(fc_attrlist, fc_numattr++,
2305 KMF_TOKEN_LABEL_ATTR, slotlabel, strlen(slotlabel));
2306 }
2307
2308 if (*kstype == KMF_KEYSTORE_OPENSSL) {
2309 if (dirpath == NULL) {
2310 kmf_set_attr_at_index(fc_attrlist, fc_numattr++,
2311 KMF_DIRPATH_ATTR, dir, strlen(dir));
2312 } else {
2313 kmf_set_attr_at_index(fc_attrlist, fc_numattr++,
2314 KMF_DIRPATH_ATTR, dirpath, strlen(dirpath));
2315 }
2316 }
2317
2318 num = 0;
2319 kmf_set_attr_at_index(fc_attrlist, fc_numattr++,
2320 KMF_COUNT_ATTR, &num, sizeof (uint32_t));
2321
2322 ret = kmf_find_cert(handle, fc_numattr, fc_attrlist);
2323 if (ret != KMF_OK || num != 1) {
2324 if (num == 0)
2325 ret = KMF_ERR_CERT_NOT_FOUND;
2326 if (num > 1)
2327 ret = KMF_ERR_CERT_MULTIPLE_FOUND;
2328 goto out;
2329 }
2330
2331 kmf_set_attr_at_index(fc_attrlist, fc_numattr,
2332 KMF_X509_DER_CERT_ATTR, &ta_retrCert, sizeof (KMF_X509_DER_CERT));
2333 fc_numattr++;
2334
2335 ret = kmf_find_cert(handle, fc_numattr, fc_attrlist);
2336 if (ret == KMF_OK) {
2337 ta_cert->Length = ta_retrCert.certificate.Length;
2338 ta_cert->Data = malloc(ta_retrCert.certificate.Length);
2339 if (ta_cert->Data == NULL) {
2340 ret = KMF_ERR_MEMORY;
2341 goto out;
2342 }
2343 (void) memcpy(ta_cert->Data, ta_retrCert.certificate.Data,
2344 ta_retrCert.certificate.Length);
2345 } else {
2346 goto out;
2347 }
2348
2349 /*
2350 * The found TA's name must be matching with issuer name in
2351 * subscriber's certificate.
2352 */
2353 (void) memset(&ta_subjectDN, 0, sizeof (ta_subjectDN));
2354
2355 ret = kmf_get_cert_subject_str(handle, ta_cert, &ta_subject);
2356 if (ret != KMF_OK)
2357 goto out;
2358
2359 ret = kmf_dn_parser(ta_subject, &ta_subjectDN);
2360 if (ret != KMF_OK)
2361 goto out;
2362
2363 if (kmf_compare_rdns(user_issuerDN, &ta_subjectDN) != 0)
2364 ret = KMF_ERR_CERT_NOT_FOUND;
2365
2366 kmf_free_dn(&ta_subjectDN);
2367
2368 /* Make sure the TA cert has the correct extensions */
2369 if (ret == KMF_OK) {
2370 ret = check_key_usage(handle, ta_cert, KMF_KU_SIGN_CERT);
2371 if (ret == KMF_ERR_EXTENSION_NOT_FOUND && policy->ku_bits == 0)
2372 ret = KMF_OK;
2373 }
2374 out:
2375 if (ta_retrCert.certificate.Data)
2376 kmf_free_kmf_cert(handle, &ta_retrCert);
2377
2378 if ((ret != KMF_OK))
2379 kmf_free_data(ta_cert);
2380
2381 if (ta_subject != NULL)
2382 free(ta_subject);
2383
2384 if (serial.val != NULL)
2385 free(serial.val);
2386
2387 return (ret);
2388 }
2389
2390 KMF_RETURN
kmf_validate_cert(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)2391 kmf_validate_cert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
2392 {
2393 KMF_RETURN ret = KMF_OK;
2394 KMF_KEYSTORE_TYPE *kstype = NULL;
2395 KMF_DATA *pcert = NULL;
2396 int *result = NULL;
2397 char *slotlabel = NULL;
2398 char *dirpath = NULL;
2399 KMF_DATA *ocsp_response = NULL;
2400 KMF_DATA ta_cert = { 0, NULL };
2401 KMF_DATA issuer_cert = { 0, NULL };
2402 char *user_issuer = NULL, *user_subject = NULL;
2403 KMF_X509_NAME user_issuerDN, user_subjectDN;
2404 boolean_t self_signed = B_FALSE;
2405 KMF_POLICY_RECORD *policy;
2406
2407 KMF_ATTRIBUTE_TESTER required_attrs[] = {
2408 {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)},
2409 {KMF_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), sizeof (KMF_DATA)},
2410 {KMF_VALIDATE_RESULT_ATTR, FALSE, 1, sizeof (int)}
2411 };
2412 int num_req_attrs = sizeof (required_attrs) /
2413 sizeof (KMF_ATTRIBUTE_TESTER);
2414
2415 if (handle == NULL)
2416 return (KMF_ERR_BAD_PARAMETER);
2417
2418 CLEAR_ERROR(handle, ret);
2419
2420 ret = test_attributes(num_req_attrs, required_attrs,
2421 0, NULL, numattr, attrlist);
2422 if (ret != KMF_OK)
2423 return (ret);
2424
2425 policy = handle->policy;
2426
2427 /* Get the attribute values */
2428 kstype = kmf_get_attr_ptr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr);
2429 pcert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr);
2430 result = kmf_get_attr_ptr(KMF_VALIDATE_RESULT_ATTR, attrlist, numattr);
2431 if (kstype == NULL || pcert == NULL || result == NULL)
2432 return (KMF_ERR_BAD_PARAMETER);
2433
2434 slotlabel = kmf_get_attr_ptr(KMF_TOKEN_LABEL_ATTR, attrlist, numattr);
2435 dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
2436 ocsp_response = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_DATA_ATTR, attrlist,
2437 numattr);
2438
2439 /* Initialize the returned result */
2440 *result = KMF_CERT_VALIDATE_OK;
2441
2442 /*
2443 * Get the issuer information from the input certficate first.
2444 */
2445 if ((ret = kmf_get_cert_issuer_str(handle, pcert,
2446 &user_issuer)) != KMF_OK) {
2447 *result |= KMF_CERT_VALIDATE_ERR_USER;
2448 } else if ((ret = kmf_dn_parser(user_issuer, &user_issuerDN)) !=
2449 KMF_OK) {
2450 *result |= KMF_CERT_VALIDATE_ERR_USER;
2451 }
2452
2453 /*
2454 * Check if the certificate is a self-signed cert.
2455 */
2456 if ((ret = kmf_get_cert_subject_str(handle, pcert,
2457 &user_subject)) != KMF_OK) {
2458 *result |= KMF_CERT_VALIDATE_ERR_USER;
2459 } else if ((ret = kmf_dn_parser(user_subject, &user_subjectDN)) !=
2460 KMF_OK) {
2461 *result |= KMF_CERT_VALIDATE_ERR_USER;
2462 }
2463
2464 if ((*result & KMF_CERT_VALIDATE_ERR_USER) == 0 &&
2465 (kmf_compare_rdns(&user_issuerDN, &user_subjectDN)) == 0) {
2466 /*
2467 * this is a self-signed cert
2468 */
2469 self_signed = B_TRUE;
2470 }
2471
2472 kmf_free_dn(&user_subjectDN);
2473
2474 /*
2475 * Check KeyUsage extension of the subscriber's certificate
2476 */
2477 ret = cert_ku_check(handle, pcert);
2478 if (ret != KMF_OK) {
2479 *result |= KMF_CERT_VALIDATE_ERR_KEYUSAGE;
2480 }
2481
2482 /*
2483 * Validate Extended KeyUsage extension
2484 */
2485 ret = cert_eku_check(handle, pcert);
2486 if (ret != KMF_OK) {
2487 *result |= KMF_CERT_VALIDATE_ERR_EXT_KEYUSAGE;
2488 }
2489
2490 /*
2491 * Check the certificate's validity period
2492 *
2493 * This step is needed when "ignore_date" in policy is set
2494 * to false.
2495 */
2496 if (!policy->ignore_date) {
2497 /*
2498 * Validate expiration date
2499 */
2500 ret = kmf_check_cert_date(handle, pcert);
2501 if (ret != KMF_OK)
2502 *result |= KMF_CERT_VALIDATE_ERR_TIME;
2503 }
2504
2505 /*
2506 * When "ignore_trust_anchor" in policy is set to FALSE,
2507 * we will try to find the TA cert based on the TA policy
2508 * attributes.
2509 *
2510 * TA's subject name (ta_name) and serial number (ta_serial)
2511 * are defined as optional attributes in policy dtd, but they
2512 * should exist in policy when "ignore_trust_anchor" is set
2513 * to FALSE. The policy verification code has enforced that.
2514 *
2515 * The serial number may be NULL if the ta_name == "search"
2516 * which indicates that KMF should try to locate the issuer
2517 * of the subject cert instead of using a specific TA name.
2518 */
2519 if (policy->ignore_trust_anchor) {
2520 goto check_revocation;
2521 }
2522
2523 /*
2524 * Verify the signature of subscriber's certificate using
2525 * TA certificate.
2526 */
2527 if (self_signed) {
2528 ret = verify_cert_with_cert(handle, pcert, pcert);
2529 if (ret != KMF_OK)
2530 *result |= KMF_CERT_VALIDATE_ERR_SIGNATURE;
2531 } else if (user_issuer != NULL) {
2532 if (policy->ta_name != NULL &&
2533 strcasecmp(policy->ta_name, "search") == 0) {
2534 ret = find_issuer_cert(handle, kstype, user_issuer,
2535 &issuer_cert, slotlabel, dirpath);
2536 if (ret != KMF_OK) {
2537 *result |= KMF_CERT_VALIDATE_ERR_TA;
2538 } else {
2539 ta_cert = issuer_cert; /* used later */
2540 }
2541 } else {
2542 /*
2543 * If we didnt find the user_issuer string, we
2544 * won't have a "user_issuerDN" either.
2545 */
2546 ret = find_ta_cert(handle, kstype, &ta_cert,
2547 &user_issuerDN, slotlabel, dirpath);
2548 }
2549 if (ret != KMF_OK) {
2550 *result |= KMF_CERT_VALIDATE_ERR_TA;
2551 }
2552
2553 /* Only verify if we got the TA without an error. */
2554 if ((*result & KMF_CERT_VALIDATE_ERR_TA) == 0) {
2555 ret = verify_cert_with_cert(handle, pcert,
2556 &ta_cert);
2557 if (ret != KMF_OK)
2558 *result |= KMF_CERT_VALIDATE_ERR_SIGNATURE;
2559 }
2560 } else {
2561 /* No issuer was found, so we cannot find a trust anchor */
2562 *result |= KMF_CERT_VALIDATE_ERR_TA;
2563 }
2564
2565 check_revocation:
2566 /*
2567 * Check certificate revocation
2568 */
2569 if (self_signed) {
2570 /* skip revocation checking */
2571 goto out;
2572 }
2573
2574 /*
2575 * When CRL or OCSP revocation method is set in the policy,
2576 * we will try to find the issuer of the subscriber certificate
2577 * using the issuer name of the subscriber certificate. The
2578 * issuer certificate will be used to do the CRL checking
2579 * and OCSP checking.
2580 */
2581 if (!(policy->revocation & KMF_REVOCATION_METHOD_CRL) &&
2582 !(policy->revocation & KMF_REVOCATION_METHOD_OCSP)) {
2583 goto out;
2584 }
2585
2586 /*
2587 * If we did not find the issuer cert earlier
2588 * (when policy->ta_name == "search"), get it here.
2589 * We need the issuer cert if the revocation method is
2590 * CRL or OCSP.
2591 */
2592 if (issuer_cert.Length == 0 &&
2593 policy->revocation & KMF_REVOCATION_METHOD_CRL ||
2594 policy->revocation & KMF_REVOCATION_METHOD_OCSP) {
2595 ret = find_issuer_cert(handle, kstype, user_issuer,
2596 &issuer_cert, slotlabel, dirpath);
2597 if (ret != KMF_OK) {
2598 *result |= KMF_CERT_VALIDATE_ERR_ISSUER;
2599 }
2600 }
2601
2602 if (policy->revocation & KMF_REVOCATION_METHOD_CRL &&
2603 (*result & KMF_CERT_VALIDATE_ERR_ISSUER) == 0) {
2604 ret = cert_crl_check(handle, kstype, pcert, &issuer_cert);
2605 if (ret != KMF_OK) {
2606 *result |= KMF_CERT_VALIDATE_ERR_CRL;
2607 }
2608 }
2609
2610 if (policy->revocation & KMF_REVOCATION_METHOD_OCSP &&
2611 (*result & KMF_CERT_VALIDATE_ERR_ISSUER) == 0) {
2612 ret = cert_ocsp_check(handle, kstype, pcert, &issuer_cert,
2613 ocsp_response, slotlabel, dirpath);
2614 if (ret != KMF_OK) {
2615 *result |= KMF_CERT_VALIDATE_ERR_OCSP;
2616 }
2617 }
2618 out:
2619 if (user_issuer) {
2620 kmf_free_dn(&user_issuerDN);
2621 free(user_issuer);
2622 }
2623
2624 if (user_subject)
2625 free(user_subject);
2626
2627 /*
2628 * If we did not copy ta_cert to issuer_cert, free it.
2629 */
2630 if (issuer_cert.Data &&
2631 issuer_cert.Data != ta_cert.Data)
2632 kmf_free_data(&issuer_cert);
2633
2634 kmf_free_data(&ta_cert);
2635
2636 /*
2637 * If we got an error flag from any of the checks,
2638 * remap the return code to a generic "CERT_VALIDATION"
2639 * error so the caller knows to check the individual flags.
2640 */
2641 if (*result != 0)
2642 ret = KMF_ERR_CERT_VALIDATION;
2643
2644 return (ret);
2645 }
2646
2647 KMF_RETURN
kmf_create_cert_file(const KMF_DATA * certdata,KMF_ENCODE_FORMAT format,char * certfile)2648 kmf_create_cert_file(const KMF_DATA *certdata, KMF_ENCODE_FORMAT format,
2649 char *certfile)
2650 {
2651 KMF_RETURN rv = KMF_OK;
2652 int fd = -1;
2653 KMF_DATA pemdata = { 0, NULL };
2654
2655 if (certdata == NULL || certfile == NULL)
2656 return (KMF_ERR_BAD_PARAMETER);
2657
2658 if (format != KMF_FORMAT_PEM && format != KMF_FORMAT_ASN1)
2659 return (KMF_ERR_BAD_PARAMETER);
2660
2661 if (format == KMF_FORMAT_PEM) {
2662 int len;
2663 rv = kmf_der_to_pem(KMF_CERT,
2664 certdata->Data, certdata->Length,
2665 &pemdata.Data, &len);
2666 if (rv != KMF_OK)
2667 goto cleanup;
2668 pemdata.Length = (size_t)len;
2669 }
2670
2671 if ((fd = open(certfile, O_CREAT | O_RDWR | O_TRUNC, 0644)) == -1) {
2672 rv = KMF_ERR_OPEN_FILE;
2673 goto cleanup;
2674 }
2675
2676 if (format == KMF_FORMAT_PEM) {
2677 if (write(fd, pemdata.Data, pemdata.Length) !=
2678 pemdata.Length) {
2679 rv = KMF_ERR_WRITE_FILE;
2680 }
2681 } else {
2682 if (write(fd, certdata->Data, certdata->Length) !=
2683 certdata->Length) {
2684 rv = KMF_ERR_WRITE_FILE;
2685 }
2686 }
2687
2688 cleanup:
2689 if (fd != -1)
2690 (void) close(fd);
2691
2692 kmf_free_data(&pemdata);
2693
2694 return (rv);
2695 }
2696
2697 /*
2698 * kmf_is_cert_data
2699 *
2700 * Determine if a KMF_DATA buffer contains an encoded X.509 certificate.
2701 *
2702 * Return:
2703 * KMF_OK if it is a certificate
2704 * KMF_ERR_ENCODING (or other error) if not.
2705 */
2706 KMF_RETURN
kmf_is_cert_data(KMF_DATA * data,KMF_ENCODE_FORMAT * fmt)2707 kmf_is_cert_data(KMF_DATA *data, KMF_ENCODE_FORMAT *fmt)
2708 {
2709 KMF_RETURN rv = KMF_OK;
2710 KMF_X509_CERTIFICATE *x509 = NULL;
2711 KMF_DATA oldpem = { 0, NULL };
2712 uchar_t *d = NULL;
2713 int len = 0;
2714
2715 if (data == NULL || fmt == NULL)
2716 return (KMF_ERR_BAD_PARAMETER);
2717
2718 rv = kmf_get_data_format(data, fmt);
2719 if (rv != KMF_OK)
2720 return (rv);
2721 switch (*fmt) {
2722 case KMF_FORMAT_ASN1:
2723 rv = DerDecodeSignedCertificate(data, &x509);
2724 break;
2725 case KMF_FORMAT_PEM:
2726 /* Convert to ASN.1 DER first */
2727 rv = kmf_pem_to_der(data->Data, data->Length,
2728 &d, &len);
2729 if (rv != KMF_OK)
2730 return (rv);
2731 oldpem.Data = d;
2732 oldpem.Length = len;
2733 rv = DerDecodeSignedCertificate(&oldpem, &x509);
2734 kmf_free_data(&oldpem);
2735 break;
2736 case KMF_FORMAT_PKCS12:
2737 case KMF_FORMAT_UNDEF:
2738 default:
2739 return (KMF_ERR_ENCODING);
2740 }
2741
2742 if (x509 != NULL) {
2743 kmf_free_signed_cert(x509);
2744 free(x509);
2745 }
2746 return (rv);
2747 }
2748
2749 KMF_RETURN
kmf_is_cert_file(KMF_HANDLE_T handle,char * filename,KMF_ENCODE_FORMAT * pformat)2750 kmf_is_cert_file(KMF_HANDLE_T handle, char *filename,
2751 KMF_ENCODE_FORMAT *pformat)
2752 {
2753 KMF_RETURN ret;
2754 KMF_DATA filedata;
2755
2756 CLEAR_ERROR(handle, ret);
2757 if (ret != KMF_OK)
2758 return (ret);
2759
2760 if (filename == NULL || pformat == NULL)
2761 return (KMF_ERR_BAD_PARAMETER);
2762
2763 ret = kmf_read_input_file(handle, filename, &filedata);
2764 if (ret != KMF_OK)
2765 return (ret);
2766
2767 ret = kmf_is_cert_data(&filedata, pformat);
2768 if (ret == KMF_ERR_BAD_CERT_FORMAT)
2769 ret = KMF_ERR_BAD_CERTFILE;
2770
2771 kmf_free_data(&filedata);
2772 return (ret);
2773 }
2774
2775 /*
2776 * This function checks the validity period of a der-encoded certificate.
2777 */
2778 KMF_RETURN
kmf_check_cert_date(KMF_HANDLE_T handle,const KMF_DATA * cert)2779 kmf_check_cert_date(KMF_HANDLE_T handle, const KMF_DATA *cert)
2780 {
2781 KMF_RETURN rv;
2782 struct tm *gmt;
2783 time_t t_now;
2784 time_t t_notbefore;
2785 time_t t_notafter;
2786 KMF_POLICY_RECORD *policy;
2787 uint32_t adj;
2788
2789 CLEAR_ERROR(handle, rv);
2790 if (rv != KMF_OK)
2791 return (rv);
2792
2793 if (cert == NULL || cert->Data == NULL || cert->Length == 0)
2794 return (KMF_ERR_BAD_PARAMETER);
2795
2796 policy = handle->policy;
2797 rv = kmf_get_cert_validity(cert, &t_notbefore, &t_notafter);
2798 if (rv != KMF_OK)
2799 return (rv);
2800
2801 /*
2802 * Get the current time. The time returned from time() is local which
2803 * cannot be used directly. It must be converted to UTC/GMT first.
2804 */
2805 t_now = time(NULL);
2806 gmt = gmtime(&t_now);
2807 t_now = mktime(gmt);
2808
2809 /*
2810 * Adjust the validity time
2811 */
2812 if (policy->validity_adjusttime != NULL) {
2813 if (str2lifetime(policy->validity_adjusttime, &adj) < 0)
2814 return (KMF_ERR_VALIDITY_PERIOD);
2815 } else {
2816 adj = 0;
2817 }
2818
2819 t_notafter += adj;
2820 t_notbefore -= adj;
2821
2822 if (t_now <= t_notafter && t_now >= t_notbefore) {
2823 rv = KMF_OK;
2824 } else {
2825 rv = KMF_ERR_VALIDITY_PERIOD;
2826 }
2827
2828 return (rv);
2829 }
2830
2831 KMF_RETURN
kmf_export_pk12(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)2832 kmf_export_pk12(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
2833 {
2834 KMF_PLUGIN *plugin;
2835 KMF_RETURN ret = KMF_OK;
2836 KMF_KEYSTORE_TYPE kstype;
2837
2838 KMF_ATTRIBUTE_TESTER required_attrs[] = {
2839 {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)},
2840 {KMF_OUTPUT_FILENAME_ATTR, TRUE, 1, 0},
2841 };
2842
2843 int num_req_attrs = sizeof (required_attrs) /
2844 sizeof (KMF_ATTRIBUTE_TESTER);
2845
2846 if (handle == NULL)
2847 return (KMF_ERR_BAD_PARAMETER);
2848
2849 CLEAR_ERROR(handle, ret);
2850
2851 ret = test_attributes(num_req_attrs, required_attrs, 0, NULL,
2852 numattr, attrlist);
2853 if (ret != KMF_OK)
2854 return (ret);
2855
2856 ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr,
2857 &kstype, NULL);
2858 if (ret != KMF_OK)
2859 return (ret);
2860
2861 plugin = FindPlugin(handle, kstype);
2862 if (plugin == NULL || plugin->funclist->ExportPK12 == NULL)
2863 return (KMF_ERR_PLUGIN_NOTFOUND);
2864
2865 return (plugin->funclist->ExportPK12(handle, numattr, attrlist));
2866 }
2867
2868
2869 KMF_RETURN
kmf_build_pk12(KMF_HANDLE_T handle,int numcerts,KMF_X509_DER_CERT * certlist,int numkeys,KMF_KEY_HANDLE * keylist,KMF_CREDENTIAL * p12cred,char * filename)2870 kmf_build_pk12(KMF_HANDLE_T handle, int numcerts,
2871 KMF_X509_DER_CERT *certlist, int numkeys, KMF_KEY_HANDLE *keylist,
2872 KMF_CREDENTIAL *p12cred, char *filename)
2873 {
2874 KMF_RETURN rv;
2875 KMF_PLUGIN *plugin;
2876 KMF_RETURN (*buildpk12)(KMF_HANDLE *, int, KMF_X509_DER_CERT *,
2877 int, KMF_KEY_HANDLE *, KMF_CREDENTIAL *, char *);
2878
2879 CLEAR_ERROR(handle, rv);
2880 if (rv != KMF_OK)
2881 return (rv);
2882
2883 if (filename == NULL || p12cred == NULL ||
2884 (certlist == NULL && keylist == NULL))
2885 return (KMF_ERR_BAD_PARAMETER);
2886
2887 plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL);
2888 if (plugin == NULL || plugin->dldesc == NULL) {
2889 return (KMF_ERR_PLUGIN_NOTFOUND);
2890 }
2891
2892 buildpk12 = (KMF_RETURN(*)())dlsym(plugin->dldesc,
2893 "openssl_build_pk12");
2894 if (buildpk12 == NULL) {
2895 return (KMF_ERR_FUNCTION_NOT_FOUND);
2896 }
2897
2898 rv = buildpk12(handle, numcerts, certlist, numkeys, keylist, p12cred,
2899 filename);
2900
2901 return (rv);
2902 }
2903
2904
2905 KMF_RETURN
kmf_import_objects(KMF_HANDLE_T handle,char * filename,KMF_CREDENTIAL * cred,KMF_X509_DER_CERT ** certs,int * ncerts,KMF_RAW_KEY_DATA ** rawkeys,int * nkeys)2906 kmf_import_objects(KMF_HANDLE_T handle, char *filename,
2907 KMF_CREDENTIAL *cred,
2908 KMF_X509_DER_CERT **certs, int *ncerts,
2909 KMF_RAW_KEY_DATA **rawkeys, int *nkeys)
2910 {
2911 KMF_RETURN rv;
2912 KMF_PLUGIN *plugin;
2913 KMF_RETURN (*import_objects)(KMF_HANDLE *, char *, KMF_CREDENTIAL *,
2914 KMF_X509_DER_CERT **, int *, KMF_RAW_KEY_DATA **, int *);
2915
2916 CLEAR_ERROR(handle, rv);
2917 if (rv != KMF_OK)
2918 return (rv);
2919
2920 if (filename == NULL || cred == NULL || certs == NULL ||
2921 ncerts == NULL ||rawkeys == NULL || nkeys == NULL)
2922 return (KMF_ERR_BAD_PARAMETER);
2923
2924 /*
2925 * Use the Keypair reader from the OpenSSL plugin.
2926 */
2927 plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL);
2928 if (plugin == NULL || plugin->dldesc == NULL) {
2929 return (KMF_ERR_PLUGIN_NOTFOUND);
2930 }
2931
2932 import_objects = (KMF_RETURN(*)())dlsym(plugin->dldesc,
2933 "openssl_import_objects");
2934 if (import_objects == NULL) {
2935 return (KMF_ERR_FUNCTION_NOT_FOUND);
2936 }
2937
2938 /* Use OpenSSL interfaces to get raw key and cert data */
2939 rv = import_objects(handle, filename, cred, certs, ncerts,
2940 rawkeys, nkeys);
2941
2942 return (rv);
2943 }
2944
2945 KMF_BOOL
IsEqualOid(KMF_OID * Oid1,KMF_OID * Oid2)2946 IsEqualOid(KMF_OID *Oid1, KMF_OID *Oid2)
2947 {
2948 return ((Oid1->Length == Oid2->Length) &&
2949 !memcmp(Oid1->Data, Oid2->Data, Oid1->Length));
2950 }
2951
2952 static KMF_RETURN
set_algoid(KMF_X509_ALGORITHM_IDENTIFIER * destid,KMF_OID * newoid)2953 set_algoid(KMF_X509_ALGORITHM_IDENTIFIER *destid,
2954 KMF_OID *newoid)
2955 {
2956 if (destid == NULL || newoid == NULL)
2957 return (KMF_ERR_BAD_PARAMETER);
2958
2959 destid->algorithm.Length = newoid->Length;
2960 destid->algorithm.Data = malloc(destid->algorithm.Length);
2961 if (destid->algorithm.Data == NULL)
2962 return (KMF_ERR_MEMORY);
2963
2964 (void) memcpy(destid->algorithm.Data, newoid->Data,
2965 destid->algorithm.Length);
2966
2967 return (KMF_OK);
2968 }
2969
2970 KMF_RETURN
copy_algoid(KMF_X509_ALGORITHM_IDENTIFIER * destid,KMF_X509_ALGORITHM_IDENTIFIER * srcid)2971 copy_algoid(KMF_X509_ALGORITHM_IDENTIFIER *destid,
2972 KMF_X509_ALGORITHM_IDENTIFIER *srcid)
2973 {
2974 KMF_RETURN ret = KMF_OK;
2975 if (!destid || !srcid)
2976 return (KMF_ERR_BAD_PARAMETER);
2977
2978 destid->algorithm.Length = srcid->algorithm.Length;
2979 destid->algorithm.Data = malloc(destid->algorithm.Length);
2980 if (destid->algorithm.Data == NULL)
2981 return (KMF_ERR_MEMORY);
2982
2983 (void) memcpy(destid->algorithm.Data, srcid->algorithm.Data,
2984 destid->algorithm.Length);
2985
2986 destid->parameters.Length = srcid->parameters.Length;
2987 if (destid->parameters.Length > 0) {
2988 destid->parameters.Data = malloc(destid->parameters.Length);
2989 if (destid->parameters.Data == NULL)
2990 return (KMF_ERR_MEMORY);
2991
2992 (void) memcpy(destid->parameters.Data, srcid->parameters.Data,
2993 destid->parameters.Length);
2994 } else {
2995 destid->parameters.Data = NULL;
2996 }
2997 return (ret);
2998 }
2999
3000 static KMF_RETURN
sign_cert(KMF_HANDLE_T handle,const KMF_DATA * SubjectCert,KMF_KEY_HANDLE * Signkey,KMF_OID * signature_oid,KMF_DATA * SignedCert)3001 sign_cert(KMF_HANDLE_T handle,
3002 const KMF_DATA *SubjectCert,
3003 KMF_KEY_HANDLE *Signkey,
3004 KMF_OID *signature_oid,
3005 KMF_DATA *SignedCert)
3006 {
3007 KMF_X509_CERTIFICATE *subj_cert = NULL;
3008 KMF_DATA data_to_sign = { 0, NULL };
3009 KMF_DATA signed_data = { 0, NULL };
3010 KMF_RETURN ret = KMF_OK;
3011 KMF_ALGORITHM_INDEX algid;
3012 int i = 0;
3013 KMF_ATTRIBUTE attrlist[8];
3014
3015 if (!SignedCert)
3016 return (KMF_ERR_BAD_PARAMETER);
3017
3018 SignedCert->Length = 0;
3019 SignedCert->Data = NULL;
3020
3021 if (!SubjectCert)
3022 return (KMF_ERR_BAD_PARAMETER);
3023
3024 if (!SubjectCert->Data || !SubjectCert->Length)
3025 return (KMF_ERR_BAD_PARAMETER);
3026
3027 /*
3028 * Shortcut - just extract the already encoded TBS cert data from
3029 * the original data buffer. Since we haven't changed anything,
3030 * there is no need to re-encode it.
3031 */
3032 ret = ExtractX509CertParts((KMF_DATA *)SubjectCert,
3033 &data_to_sign, NULL);
3034 if (ret != KMF_OK) {
3035 goto cleanup;
3036 }
3037
3038 /* Estimate the signed data length generously */
3039 signed_data.Length = data_to_sign.Length*2;
3040 signed_data.Data = calloc(1, signed_data.Length);
3041 if (!signed_data.Data) {
3042 ret = KMF_ERR_MEMORY;
3043 goto cleanup;
3044 }
3045
3046 /*
3047 * If we got here OK, decode into a structure and then re-encode
3048 * the complete certificate.
3049 */
3050 ret = DerDecodeSignedCertificate(SubjectCert, &subj_cert);
3051 if (ret != KMF_OK) {
3052 goto cleanup;
3053 }
3054
3055 /* We are re-signing this cert, so clear out old signature data */
3056 if (!IsEqualOid(&subj_cert->signature.algorithmIdentifier.algorithm,
3057 signature_oid)) {
3058 kmf_free_algoid(&subj_cert->signature.algorithmIdentifier);
3059 ret = set_algoid(&subj_cert->signature.algorithmIdentifier,
3060 signature_oid);
3061 if (ret != KMF_OK)
3062 goto cleanup;
3063 ret = set_algoid(&subj_cert->certificate.signature,
3064 signature_oid);
3065 if (ret)
3066 goto cleanup;
3067
3068 /* Free the previous "data to be signed" block */
3069 kmf_free_data(&data_to_sign);
3070
3071 /*
3072 * We changed the cert (updated the signature OID), so we
3073 * need to re-encode it so the correct data gets signed.
3074 */
3075 ret = DerEncodeTbsCertificate(&subj_cert->certificate,
3076 &data_to_sign);
3077 if (ret != KMF_OK)
3078 goto cleanup;
3079 }
3080 kmf_set_attr_at_index(attrlist, i, KMF_KEYSTORE_TYPE_ATTR,
3081 &Signkey->kstype, sizeof (KMF_KEYSTORE_TYPE));
3082 i++;
3083 kmf_set_attr_at_index(attrlist, i, KMF_KEY_HANDLE_ATTR,
3084 Signkey, sizeof (KMF_KEY_HANDLE));
3085 i++;
3086 kmf_set_attr_at_index(attrlist, i, KMF_DATA_ATTR,
3087 &data_to_sign, sizeof (KMF_DATA));
3088 i++;
3089 kmf_set_attr_at_index(attrlist, i, KMF_OUT_DATA_ATTR,
3090 &signed_data, sizeof (KMF_DATA));
3091 i++;
3092 kmf_set_attr_at_index(attrlist, i, KMF_OID_ATTR,
3093 signature_oid, sizeof (KMF_OID));
3094 i++;
3095
3096 /* Sign the data */
3097 ret = kmf_sign_data(handle, i, attrlist);
3098
3099 if (ret != KMF_OK)
3100 goto cleanup;
3101
3102 algid = x509_algoid_to_algid(signature_oid);
3103
3104 if (algid == KMF_ALGID_SHA1WithECDSA ||
3105 algid == KMF_ALGID_SHA256WithECDSA ||
3106 algid == KMF_ALGID_SHA384WithECDSA ||
3107 algid == KMF_ALGID_SHA512WithECDSA) {
3108 /* ASN.1 encode ECDSA signature */
3109 KMF_DATA signature;
3110
3111 ret = DerEncodeECDSASignature(&signed_data, &signature);
3112 kmf_free_data(&signed_data);
3113
3114 if (ret != KMF_OK)
3115 goto cleanup;
3116
3117 subj_cert->signature.encrypted = signature;
3118 } else if (algid == KMF_ALGID_SHA1WithDSA ||
3119 algid == KMF_ALGID_SHA256WithDSA) {
3120 /*
3121 * For DSA, kmf_sign_data() returns a 40-byte
3122 * signature. We must encode the signature correctly.
3123 */
3124 KMF_DATA signature;
3125
3126 ret = DerEncodeDSASignature(&signed_data, &signature);
3127 kmf_free_data(&signed_data);
3128
3129 if (ret != KMF_OK)
3130 goto cleanup;
3131
3132 subj_cert->signature.encrypted = signature;
3133 } else {
3134 ret = copy_data(&subj_cert->signature.encrypted, &signed_data);
3135 kmf_free_data(&signed_data);
3136
3137 if (ret != KMF_OK)
3138 goto cleanup;
3139 }
3140
3141 /* Now, re-encode the cert with the new signature */
3142 ret = DerEncodeSignedCertificate(subj_cert, SignedCert);
3143
3144 cleanup:
3145 /* Cleanup & return */
3146 if (ret != KMF_OK)
3147 kmf_free_data(SignedCert);
3148
3149 kmf_free_data(&data_to_sign);
3150
3151 if (subj_cert != NULL) {
3152 kmf_free_signed_cert(subj_cert);
3153 free(subj_cert);
3154 }
3155
3156 return (ret);
3157 }
3158
3159 static KMF_RETURN
verify_cert_with_key(KMF_HANDLE_T handle,KMF_DATA * derkey,const KMF_DATA * CertToBeVerified)3160 verify_cert_with_key(KMF_HANDLE_T handle,
3161 KMF_DATA *derkey,
3162 const KMF_DATA *CertToBeVerified)
3163 {
3164 KMF_RETURN ret = KMF_OK;
3165 KMF_X509_CERTIFICATE *signed_cert = NULL;
3166 KMF_X509_SPKI spki;
3167 KMF_DATA data_to_verify = { 0, NULL };
3168 KMF_DATA signed_data = { 0, NULL };
3169 KMF_DATA signature = { 0, NULL };
3170 KMF_ALGORITHM_INDEX algid;
3171
3172 /* check the caller and do other setup for this SPI call */
3173 if (handle == NULL || CertToBeVerified == NULL ||
3174 derkey == NULL || derkey->Data == NULL)
3175 return (KMF_ERR_BAD_PARAMETER);
3176
3177 (void) memset(&spki, 0, sizeof (KMF_X509_SPKI));
3178
3179 ret = ExtractX509CertParts((KMF_DATA *)CertToBeVerified,
3180 &data_to_verify, &signed_data);
3181
3182 if (ret != KMF_OK)
3183 goto cleanup;
3184
3185 ret = DerDecodeSPKI(derkey, &spki);
3186 if (ret != KMF_OK)
3187 goto cleanup;
3188
3189 /* Decode the signer cert so we can get the Algorithm data */
3190 ret = DerDecodeSignedCertificate(CertToBeVerified, &signed_cert);
3191 if (ret != KMF_OK)
3192 return (ret);
3193
3194 algid = x509_algoid_to_algid(CERT_SIG_OID(signed_cert));
3195
3196 if (algid == KMF_ALGID_NONE)
3197 return (KMF_ERR_BAD_ALGORITHM);
3198
3199 if (algid == KMF_ALGID_SHA1WithDSA ||
3200 algid == KMF_ALGID_SHA256WithDSA) {
3201 ret = DerDecodeDSASignature(&signed_data, &signature);
3202 if (ret != KMF_OK)
3203 goto cleanup;
3204 } else if (algid == KMF_ALGID_SHA1WithECDSA ||
3205 algid == KMF_ALGID_SHA256WithECDSA ||
3206 algid == KMF_ALGID_SHA384WithECDSA ||
3207 algid == KMF_ALGID_SHA512WithECDSA) {
3208 ret = DerDecodeECDSASignature(&signed_data, &signature);
3209 if (ret != KMF_OK)
3210 goto cleanup;
3211 } else {
3212 signature.Data = signed_data.Data;
3213 signature.Length = signed_data.Length;
3214 }
3215
3216 ret = PKCS_VerifyData(handle, algid, &spki,
3217 &data_to_verify, &signature);
3218
3219 cleanup:
3220 if (data_to_verify.Data != NULL)
3221 free(data_to_verify.Data);
3222
3223 if (signed_data.Data != NULL)
3224 free(signed_data.Data);
3225
3226 if (signed_cert) {
3227 kmf_free_signed_cert(signed_cert);
3228 free(signed_cert);
3229 }
3230 if (algid == KMF_ALGID_SHA1WithDSA ||
3231 algid == KMF_ALGID_SHA256WithDSA ||
3232 algid == KMF_ALGID_SHA1WithECDSA ||
3233 algid == KMF_ALGID_SHA256WithECDSA ||
3234 algid == KMF_ALGID_SHA384WithECDSA ||
3235 algid == KMF_ALGID_SHA512WithECDSA) {
3236 free(signature.Data);
3237 }
3238
3239 kmf_free_algoid(&spki.algorithm);
3240 kmf_free_data(&spki.subjectPublicKey);
3241
3242 return (ret);
3243 }
3244
3245 /*
3246 * Use a signer cert to verify another certificate's signature.
3247 * This code forces the use of the PKCS11 mechanism for the verify
3248 * operation for the Cryptographic Framework's FIPS-140 boundary.
3249 */
3250 static KMF_RETURN
verify_cert_with_cert(KMF_HANDLE_T handle,const KMF_DATA * CertToBeVerifiedData,const KMF_DATA * SignerCertData)3251 verify_cert_with_cert(KMF_HANDLE_T handle,
3252 const KMF_DATA *CertToBeVerifiedData,
3253 const KMF_DATA *SignerCertData)
3254 {
3255 KMF_RETURN ret = KMF_OK;
3256 KMF_X509_CERTIFICATE *SignerCert = NULL;
3257 KMF_X509_CERTIFICATE *ToBeVerifiedCert = NULL;
3258 KMF_DATA data_to_verify = { 0, NULL };
3259 KMF_DATA signed_data = { 0, NULL };
3260 KMF_DATA signature;
3261 KMF_ALGORITHM_INDEX algid;
3262 KMF_POLICY_RECORD *policy;
3263
3264 if (handle == NULL ||
3265 !CertToBeVerifiedData ||
3266 !CertToBeVerifiedData->Data ||
3267 !CertToBeVerifiedData->Length)
3268 return (KMF_ERR_BAD_PARAMETER);
3269
3270 if (!SignerCertData ||
3271 !SignerCertData->Data ||
3272 !SignerCertData->Length)
3273 return (KMF_ERR_BAD_PARAMETER);
3274
3275 policy = handle->policy;
3276
3277 /* Make sure the signer has proper key usage bits */
3278 ret = check_key_usage(handle, SignerCertData, KMF_KU_SIGN_CERT);
3279 if (ret == KMF_ERR_EXTENSION_NOT_FOUND && policy->ku_bits == 0)
3280 ret = KMF_OK;
3281 if (ret != KMF_OK)
3282 return (ret);
3283
3284 /* Decode the cert into parts for verification */
3285 ret = ExtractX509CertParts((KMF_DATA *)CertToBeVerifiedData,
3286 &data_to_verify, &signed_data);
3287 if (ret != KMF_OK)
3288 goto cleanup;
3289
3290 /* Decode the to-be-verified cert so we know what algorithm to use */
3291 ret = DerDecodeSignedCertificate(CertToBeVerifiedData,
3292 &ToBeVerifiedCert);
3293 if (ret != KMF_OK)
3294 goto cleanup;
3295
3296 algid = x509_algoid_to_algid(CERT_SIG_OID(ToBeVerifiedCert));
3297
3298 if (algid == KMF_ALGID_SHA1WithDSA ||
3299 algid == KMF_ALGID_SHA256WithDSA) {
3300 ret = DerDecodeDSASignature(&signed_data, &signature);
3301 if (ret != KMF_OK)
3302 goto cleanup;
3303 } else if (algid == KMF_ALGID_SHA1WithECDSA ||
3304 algid == KMF_ALGID_SHA256WithECDSA ||
3305 algid == KMF_ALGID_SHA384WithECDSA ||
3306 algid == KMF_ALGID_SHA512WithECDSA) {
3307 ret = DerDecodeECDSASignature(&signed_data, &signature);
3308 if (ret != KMF_OK)
3309 goto cleanup;
3310 } else {
3311 signature.Data = signed_data.Data;
3312 signature.Length = signed_data.Length;
3313 }
3314
3315 ret = DerDecodeSignedCertificate(SignerCertData, &SignerCert);
3316 if (ret != KMF_OK)
3317 goto cleanup;
3318
3319 /*
3320 * Force use of PKCS11 API for kcfd/libelfsign. This is
3321 * required for the Cryptographic Framework's FIPS-140 boundary.
3322 */
3323 ret = PKCS_VerifyData(handle, algid,
3324 &SignerCert->certificate.subjectPublicKeyInfo,
3325 &data_to_verify, &signature);
3326
3327 cleanup:
3328 kmf_free_data(&data_to_verify);
3329 kmf_free_data(&signed_data);
3330
3331 if (SignerCert) {
3332 kmf_free_signed_cert(SignerCert);
3333 free(SignerCert);
3334 }
3335
3336 if (ToBeVerifiedCert) {
3337 kmf_free_signed_cert(ToBeVerifiedCert);
3338 free(ToBeVerifiedCert);
3339 }
3340
3341 if (algid == KMF_ALGID_SHA1WithDSA ||
3342 algid == KMF_ALGID_SHA256WithDSA ||
3343 algid == KMF_ALGID_SHA1WithECDSA ||
3344 algid == KMF_ALGID_SHA256WithECDSA ||
3345 algid == KMF_ALGID_SHA384WithECDSA ||
3346 algid == KMF_ALGID_SHA512WithECDSA) {
3347 free(signature.Data);
3348 }
3349
3350 return (ret);
3351 }
3352