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) 2008, 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 <errno.h>
32 #include <sys/socket.h>
33 #include <netinet/in.h>
34 #include <arpa/inet.h>
35 #include <ber_der.h>
36 #include <kmfapiP.h>
37 #include <libgen.h>
38 #include <cryptoutil.h>
39
40 KMF_RETURN
copy_data(KMF_DATA * dst,KMF_DATA * src)41 copy_data(KMF_DATA *dst, KMF_DATA *src)
42 {
43 KMF_RETURN ret = KMF_OK;
44
45 if (dst == NULL || src == NULL)
46 return (KMF_ERR_BAD_PARAMETER);
47
48 if (src->Length == 0) {
49 dst->Length = 0;
50 dst->Data = NULL;
51 src->Data = NULL;
52 return (ret);
53 }
54
55 dst->Data = malloc(src->Length);
56 if (dst->Data == NULL)
57 return (KMF_ERR_MEMORY);
58
59 dst->Length = src->Length;
60 (void) memcpy(dst->Data, src->Data, src->Length);
61
62 return (ret);
63 }
64
65 KMF_RETURN
copy_extension_data(KMF_X509_EXTENSION * dstext,KMF_X509_EXTENSION * srcext)66 copy_extension_data(KMF_X509_EXTENSION *dstext,
67 KMF_X509_EXTENSION *srcext)
68 {
69 KMF_RETURN ret = KMF_OK;
70
71 if (dstext == NULL || srcext == NULL)
72 return (KMF_ERR_BAD_PARAMETER);
73
74 (void) memset(dstext, 0, sizeof (KMF_X509_EXTENSION));
75
76 ret = copy_data(&dstext->extnId, &srcext->extnId);
77 if (ret != KMF_OK)
78 goto cleanup;
79
80 dstext->extnId.Length = srcext->extnId.Length;
81 dstext->critical = srcext->critical;
82 dstext->format = srcext->format;
83
84 ret = copy_data(&dstext->BERvalue, &srcext->BERvalue);
85 if (ret != KMF_OK)
86 goto cleanup;
87
88 dstext->value.tagAndValue = malloc(sizeof (KMF_X509EXT_TAGandVALUE));
89 if (dstext->value.tagAndValue == NULL) {
90 ret = KMF_ERR_MEMORY;
91 goto cleanup;
92 }
93 (void) memset(dstext->value.tagAndValue, 0,
94 sizeof (KMF_X509EXT_TAGandVALUE));
95
96 ret = copy_data(&dstext->value.tagAndValue->value,
97 &srcext->value.tagAndValue->value);
98 if (ret != KMF_OK)
99 goto cleanup;
100
101 dstext->value.tagAndValue->type = srcext->value.tagAndValue->type;
102
103 cleanup:
104 if (ret != KMF_OK) {
105 if (dstext->extnId.Data != NULL)
106 kmf_free_data(&dstext->extnId);
107
108 if (dstext->BERvalue.Data != NULL)
109 kmf_free_data(&dstext->BERvalue);
110
111 if (dstext->value.tagAndValue->value.Data == NULL)
112 kmf_free_data(&dstext->value.tagAndValue->value);
113 }
114
115 return (ret);
116 }
117
118 /*
119 * Given a block of DER encoded X.509 certificate data and
120 * an OID for the desired extension, this routine will
121 * parse the cert data and return the data associated with
122 * the extension if it is found.
123 *
124 * RETURNS:
125 * KMF_OK - if extension found and copied OK.
126 * KMF_ERR_EXTENSION_NOT_FOUND - extension not found.
127 * parsing and memory allocation errors are also possible.
128 */
129 KMF_RETURN
kmf_get_cert_extn(const KMF_DATA * certdata,KMF_OID * extoid,KMF_X509_EXTENSION * extdata)130 kmf_get_cert_extn(const KMF_DATA *certdata,
131 KMF_OID *extoid, KMF_X509_EXTENSION *extdata)
132 {
133 KMF_RETURN ret = KMF_OK;
134 KMF_X509_CERTIFICATE *cert = NULL;
135 KMF_X509_EXTENSION *eptr = NULL;
136 int i, found = 0;
137
138 if (certdata == NULL || extoid == NULL || extdata == NULL)
139 return (KMF_ERR_BAD_PARAMETER);
140
141 ret = DerDecodeSignedCertificate(certdata, &cert);
142 if (ret != KMF_OK)
143 return (ret);
144
145 if (cert->certificate.extensions.numberOfExtensions == 0) {
146 goto end;
147 }
148
149 (void) memset((void *)extdata, 0, sizeof (KMF_X509_EXTENSION));
150 for (i = 0; !found &&
151 i < cert->certificate.extensions.numberOfExtensions;
152 i++) {
153 eptr = &cert->certificate.extensions.extensions[i];
154 if (IsEqualOid(extoid, &eptr->extnId)) {
155 ret = copy_extension_data(extdata, eptr);
156 found++;
157 }
158 }
159 end:
160 if (!found)
161 ret = KMF_ERR_EXTENSION_NOT_FOUND;
162
163 if (cert != NULL) {
164 kmf_free_signed_cert(cert);
165 free(cert);
166 }
167
168 return (ret);
169 }
170
171 /*
172 * Given a block of DER encoded X.509 certificate data and
173 * a "crit/non-crit/all" flag, search the extensions and
174 * return the OIDs for critical, non-critical or all extensions.
175 *
176 * RETURNS:
177 * KMF_OK - if extension found and copied OK.
178 * parsing and memory allocation errors are also possible.
179 *
180 * OIDlist - array of KMF_OID records, allocated
181 * by this function.
182 * NumOIDs - number of critical extensions found.
183 */
184 KMF_RETURN
kmf_get_cert_extns(const KMF_DATA * certdata,KMF_FLAG_CERT_EXTN flag,KMF_X509_EXTENSION ** extlist,int * nextns)185 kmf_get_cert_extns(const KMF_DATA *certdata, KMF_FLAG_CERT_EXTN flag,
186 KMF_X509_EXTENSION **extlist, int *nextns)
187 {
188 KMF_RETURN ret = KMF_OK;
189 KMF_X509_CERTIFICATE *cert;
190 KMF_X509_EXTENSION *eptr, *elist;
191 int i;
192
193 if (certdata == NULL || extlist == NULL || nextns == NULL)
194 return (KMF_ERR_BAD_PARAMETER);
195
196 if (flag < KMF_ALL_EXTNS || flag > KMF_NONCRITICAL_EXTNS)
197 return (KMF_ERR_BAD_PARAMETER);
198
199 *nextns = 0;
200 *extlist = elist = NULL;
201 ret = DerDecodeSignedCertificate(certdata, &cert);
202 if (ret != KMF_OK)
203 return (ret);
204
205 if (cert->certificate.extensions.numberOfExtensions == 0)
206 return (KMF_ERR_EXTENSION_NOT_FOUND);
207
208 for (i = 0; i < cert->certificate.extensions.numberOfExtensions;
209 i++) {
210 eptr = &cert->certificate.extensions.extensions[i];
211
212 if (flag == KMF_CRITICAL_EXTNS && eptr->critical == 0)
213 continue;
214 else if (flag == KMF_NONCRITICAL_EXTNS && eptr->critical != 0)
215 continue;
216
217 (*nextns)++;
218 elist = realloc(elist, sizeof (KMF_X509_EXTENSION) *
219 (*nextns));
220 if (elist == NULL) {
221 ret = KMF_ERR_MEMORY;
222 goto end;
223 }
224
225 ret = copy_extension_data(&elist[(*nextns) - 1], eptr);
226 if (ret != KMF_OK)
227 goto end;
228 }
229
230 end:
231 kmf_free_signed_cert(cert);
232 free(cert);
233 if (ret != KMF_OK) {
234 if (elist != NULL) {
235 free(elist);
236 elist = NULL;
237 }
238 *nextns = 0;
239 }
240
241 /*
242 * If the flag is not all, then it is possible that we did not find
243 * any critical or non_critical extensions. When that happened,
244 * return KMF_ERR_EXTENSION_NOT_FOUND.
245 */
246 if (flag != KMF_ALL_EXTNS && ret == KMF_OK && *nextns == 0)
247 ret = KMF_ERR_EXTENSION_NOT_FOUND;
248
249 *extlist = elist;
250 return (ret);
251 }
252
253 /*
254 * If the given certificate data (X.509 DER encoded data)
255 * contains the Key Usage extension, parse that
256 * data and return it in the KMF_X509EXT_BASICCONSTRAINTS
257 * record.
258 *
259 * RETURNS:
260 * KMF_OK - success
261 * KMF_ERR_BAD_PARAMETER - input data was bad.
262 * KMF_ERR_EXTENSION_NOT_FOUND - extension not found.
263 */
264 KMF_RETURN
kmf_get_cert_ku(const KMF_DATA * certdata,KMF_X509EXT_KEY_USAGE * keyusage)265 kmf_get_cert_ku(const KMF_DATA *certdata,
266 KMF_X509EXT_KEY_USAGE *keyusage)
267 {
268 KMF_RETURN ret = KMF_OK;
269 KMF_X509_EXTENSION extn;
270
271 if (certdata == NULL || keyusage == NULL)
272 return (KMF_ERR_BAD_PARAMETER);
273
274 (void) memset(&extn, 0, sizeof (extn));
275 /*
276 * Check standard KeyUsage bits
277 */
278 ret = kmf_get_cert_extn(certdata, (KMF_OID *)&KMFOID_KeyUsage, &extn);
279
280 if (ret != KMF_OK) {
281 goto end;
282 }
283 keyusage->critical = (extn.critical != 0);
284 if (extn.value.tagAndValue->value.Length > 1) {
285 keyusage->KeyUsageBits =
286 extn.value.tagAndValue->value.Data[1] << 8;
287 } else {
288 keyusage->KeyUsageBits = extn.value.tagAndValue->value.Data[0];
289 }
290 end:
291 kmf_free_extn(&extn);
292 return (ret);
293 }
294
295 KMF_BOOL
is_eku_present(KMF_X509EXT_EKU * ekuptr,KMF_OID * ekuoid)296 is_eku_present(KMF_X509EXT_EKU *ekuptr, KMF_OID *ekuoid)
297 {
298 int i;
299
300 if (ekuptr == NULL || ekuoid == NULL)
301 return (0);
302
303 for (i = 0; i < ekuptr->nEKUs; i++)
304 if (IsEqualOid(&ekuptr->keyPurposeIdList[i], ekuoid))
305 return (1);
306
307 return (0);
308 }
309
310 KMF_RETURN
parse_eku_data(const KMF_DATA * asn1data,KMF_X509EXT_EKU * ekuptr)311 parse_eku_data(const KMF_DATA *asn1data, KMF_X509EXT_EKU *ekuptr)
312 {
313 KMF_RETURN ret = KMF_OK;
314 BerElement *asn1 = NULL;
315 BerValue exdata;
316 KMF_OID oid;
317 char *end = NULL;
318 ber_len_t size;
319
320 /*
321 * Decode the ASN.1 data for the extension.
322 */
323 exdata.bv_val = (char *)asn1data->Data;
324 exdata.bv_len = asn1data->Length;
325
326 if ((asn1 = kmfder_init(&exdata)) == NULL) {
327 ret = KMF_ERR_MEMORY;
328 goto end;
329 }
330
331 /*
332 * certificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation
333 */
334 if (kmfber_first_element(asn1, &size, &end) != BER_OBJECT_IDENTIFIER) {
335 ret = KMF_ERR_BAD_CERT_FORMAT;
336 goto end;
337 }
338
339 /*
340 * Count the number of EKU OIDs and store in
341 * the array.
342 */
343 while (kmfber_next_element(asn1, &size, end) ==
344 BER_OBJECT_IDENTIFIER) {
345
346 /* Skip over the CONSTRUCTED SET tag */
347 if (kmfber_scanf(asn1, "D", &oid) == KMFBER_DEFAULT) {
348 ret = KMF_ERR_BAD_CERT_FORMAT;
349 goto end;
350 }
351 ekuptr->nEKUs++;
352 ekuptr->keyPurposeIdList = realloc(ekuptr->keyPurposeIdList,
353 ekuptr->nEKUs * sizeof (KMF_OID));
354 if (ekuptr->keyPurposeIdList == NULL) {
355 ret = KMF_ERR_MEMORY;
356 goto end;
357 }
358 ekuptr->keyPurposeIdList[ekuptr->nEKUs - 1] = oid;
359 }
360
361 end:
362 if (asn1 != NULL)
363 kmfber_free(asn1, 1);
364
365 if (ret != KMF_OK) {
366 if (ekuptr->keyPurposeIdList != NULL) {
367 free_keyidlist(ekuptr->keyPurposeIdList, ekuptr->nEKUs);
368 ekuptr->keyPurposeIdList = NULL;
369 ekuptr->critical = 0;
370 }
371 }
372
373 return (ret);
374 }
375
376 KMF_RETURN
kmf_get_cert_eku(const KMF_DATA * certdata,KMF_X509EXT_EKU * ekuptr)377 kmf_get_cert_eku(const KMF_DATA *certdata,
378 KMF_X509EXT_EKU *ekuptr)
379 {
380 KMF_RETURN ret = KMF_OK;
381 KMF_X509_EXTENSION extn;
382
383 if (certdata == NULL || ekuptr == NULL)
384 return (KMF_ERR_BAD_PARAMETER);
385
386 (void) memset(&extn, 0, sizeof (KMF_X509_EXTENSION));
387
388 ekuptr->nEKUs = 0;
389 ekuptr->keyPurposeIdList = NULL;
390 ekuptr->critical = 0;
391
392 ret = kmf_get_cert_extn(certdata,
393 (KMF_OID *)&KMFOID_ExtendedKeyUsage, &extn);
394
395 if (ret != KMF_OK) {
396 goto end;
397 }
398
399 ret = parse_eku_data(&extn.BERvalue, ekuptr);
400
401 end:
402 kmf_free_extn(&extn);
403
404 return (ret);
405 }
406
407 /*
408 * If the given certificate data (X.509 DER encoded data)
409 * contains the Basic Constraints extension, parse that
410 * data and return it in the KMF_X509EXT_BASICCONSTRAINTS
411 * record.
412 *
413 * RETURNS:
414 * KMF_OK - success
415 * KMF_ERR_BAD_PARAMETER - input data was bad.
416 * KMF_ERR_EXTENSION_NOT_FOUND - extension not found.
417 */
418 KMF_RETURN
kmf_get_cert_basic_constraint(const KMF_DATA * certdata,KMF_BOOL * critical,KMF_X509EXT_BASICCONSTRAINTS * constraint)419 kmf_get_cert_basic_constraint(const KMF_DATA *certdata,
420 KMF_BOOL *critical, KMF_X509EXT_BASICCONSTRAINTS *constraint)
421 {
422 KMF_RETURN ret = KMF_OK;
423 KMF_X509_EXTENSION extn;
424 BerElement *asn1 = NULL;
425 BerValue exdata;
426 ber_len_t size;
427 char *end = NULL;
428 int tag;
429
430 if (certdata == NULL || constraint == NULL || critical == NULL)
431 return (KMF_ERR_BAD_PARAMETER);
432
433 (void) memset(&extn, 0, sizeof (KMF_X509_EXTENSION));
434 ret = kmf_get_cert_extn(certdata,
435 (KMF_OID *)&KMFOID_BasicConstraints, &extn);
436
437 if (ret != KMF_OK) {
438 goto end;
439 }
440
441 *critical = (extn.critical != 0);
442
443 exdata.bv_val = (char *)extn.value.tagAndValue->value.Data;
444 exdata.bv_len = extn.value.tagAndValue->value.Length;
445
446 if ((asn1 = kmfder_init(&exdata)) == NULL) {
447 ret = KMF_ERR_MEMORY;
448 goto end;
449 }
450
451 if (kmfber_scanf(asn1, "b", &constraint->cA) == KMFBER_DEFAULT) {
452 ret = KMF_ERR_BAD_CERT_FORMAT;
453 goto end;
454 }
455 constraint->pathLenConstraintPresent = KMF_FALSE;
456
457 tag = kmfber_next_element(asn1, &size, end);
458 if (tag == BER_INTEGER) {
459 if (kmfber_scanf(asn1, "i",
460 &constraint->pathLenConstraint) == KMFBER_DEFAULT) {
461 ret = KMF_ERR_BAD_CERT_FORMAT;
462 goto end;
463 }
464 constraint->pathLenConstraintPresent = KMF_TRUE;
465 }
466 end:
467 kmf_free_extn(&extn);
468 if (asn1 != NULL)
469 kmfber_free(asn1, 1);
470
471 return (ret);
472 }
473
474 static KMF_X509EXT_POLICYQUALIFIERINFO *
get_pqinfo(BerElement * asn1)475 get_pqinfo(BerElement *asn1)
476 {
477 KMF_X509EXT_POLICYQUALIFIERINFO *pqinfo = NULL;
478 KMF_RETURN ret = KMF_OK;
479 int tag;
480 ber_len_t size;
481 char *end = NULL;
482
483 /*
484 * Policy Qualifiers may be a list of sequences.
485 *
486 * PolicyInformation ::= SEQUENCE {
487 * policyIdentifier CertPolicyId,
488 * policyQualifiers SEQUENCE SIZE (1..MAX) OF
489 * PolicyQualifierInfo OPTIONAL
490 * }
491 *
492 * PolicyQualifierInfo ::= SEQUENCE {
493 * policyQualifierId PolicyQualifierId,
494 * qualifier ANY DEFINED BY policyQualifierId
495 * }
496 */
497
498
499 /*
500 * We already got the CertPolicyId, we just need to
501 * find all of the policyQualifiers in the set.
502 *
503 * Mark the first element of the SEQUENCE and reset the end ptr
504 * so the ber/der code knows when to stop looking.
505 */
506 if ((tag = kmfber_first_element(asn1, &size, &end)) !=
507 BER_CONSTRUCTED_SEQUENCE) {
508 ret = KMF_ERR_BAD_CERT_FORMAT;
509 goto end;
510 }
511 /* We found a sequence, loop until done */
512 while ((tag = kmfber_next_element(asn1, &size, end)) ==
513 BER_CONSTRUCTED_SEQUENCE) {
514
515 /* Skip over the CONSTRUCTED SET tag */
516 if (kmfber_scanf(asn1, "T", &tag) == KMFBER_DEFAULT) {
517 ret = KMF_ERR_BAD_CERT_FORMAT;
518 goto end;
519 }
520 /*
521 * Allocate memory for the Policy Qualifier Info
522 */
523 pqinfo = malloc(sizeof (KMF_X509EXT_POLICYQUALIFIERINFO));
524 if (pqinfo == NULL) {
525 ret = KMF_ERR_MEMORY;
526 goto end;
527 }
528 (void) memset((void *)pqinfo, 0,
529 sizeof (KMF_X509EXT_POLICYQUALIFIERINFO));
530 /*
531 * Read the PolicyQualifier OID
532 */
533 if (kmfber_scanf(asn1, "D",
534 &pqinfo->policyQualifierId) == KMFBER_DEFAULT) {
535 ret = KMF_ERR_BAD_CERT_FORMAT;
536 goto end;
537 }
538 /*
539 * The OID of the policyQualifierId determines what
540 * sort of data comes next.
541 */
542 if (IsEqualOid(&pqinfo->policyQualifierId,
543 (KMF_OID *)&KMFOID_PKIX_PQ_CPSuri)) {
544 /*
545 * CPS uri must be an IA5STRING
546 */
547 if (kmfber_scanf(asn1, "tl", &tag, &size) ==
548 KMFBER_DEFAULT || tag != BER_IA5STRING ||
549 size == 0) {
550 ret = KMF_ERR_BAD_CERT_FORMAT;
551 goto end;
552 }
553 if ((pqinfo->value.Data = malloc(size)) == NULL) {
554 ret = KMF_ERR_MEMORY;
555 goto end;
556 }
557 if (kmfber_scanf(asn1, "s", pqinfo->value.Data,
558 &pqinfo->value.Length) == KMFBER_DEFAULT) {
559 ret = KMF_ERR_BAD_CERT_FORMAT;
560 goto end;
561 }
562 } else if (IsEqualOid(&pqinfo->policyQualifierId,
563 (KMF_OID *)&KMFOID_PKIX_PQ_Unotice)) {
564 if (kmfber_scanf(asn1, "tl", &tag, &size) ==
565 KMFBER_DEFAULT ||
566 tag != BER_CONSTRUCTED_SEQUENCE) {
567 ret = KMF_ERR_BAD_CERT_FORMAT;
568 goto end;
569 }
570 /*
571 * For now, just copy the while UserNotice ASN.1
572 * blob into the pqinfo data record.
573 * TBD - parse it into individual fields.
574 */
575 if ((pqinfo->value.Data = malloc(size)) == NULL) {
576 ret = KMF_ERR_MEMORY;
577 goto end;
578 }
579 if (kmfber_scanf(asn1, "s", pqinfo->value.Data,
580 &pqinfo->value.Length) == KMFBER_DEFAULT) {
581 ret = KMF_ERR_BAD_CERT_FORMAT;
582 goto end;
583 }
584 } else {
585 ret = KMF_ERR_BAD_CERT_FORMAT;
586 goto end;
587 }
588 }
589 end:
590 if (ret != KMF_OK) {
591 if (pqinfo != NULL) {
592 kmf_free_data(&pqinfo->value);
593 kmf_free_data(&pqinfo->policyQualifierId);
594 free(pqinfo);
595 pqinfo = NULL;
596 }
597 }
598 return (pqinfo);
599 }
600
601 /*
602 * If the given certificate data (X.509 DER encoded data)
603 * contains the Certificate Policies extension, parse that
604 * data and return it in the KMF_X509EXT_CERT_POLICIES
605 * record.
606 *
607 * RETURNS:
608 * KMF_OK - success
609 * KMF_ERR_BAD_PARAMETER - input data was bad.
610 * KMF_ERR_EXTENSION_NOT_FOUND - extension not found.
611 * parsing and memory allocation errors are also possible.
612 */
613 KMF_RETURN
kmf_get_cert_policies(const KMF_DATA * certdata,KMF_BOOL * critical,KMF_X509EXT_CERT_POLICIES * extptr)614 kmf_get_cert_policies(const KMF_DATA *certdata,
615 KMF_BOOL *critical, KMF_X509EXT_CERT_POLICIES *extptr)
616 {
617 KMF_RETURN ret = KMF_OK;
618 KMF_X509_EXTENSION extn;
619 KMF_X509EXT_POLICYINFO *pinfo;
620 KMF_X509EXT_POLICYQUALIFIERINFO *pqinfo;
621 BerElement *asn1 = NULL;
622 BerValue exdata;
623 ber_len_t size;
624 char *end = NULL;
625 int tag;
626
627 if (certdata == NULL || critical == NULL || extptr == NULL)
628 return (KMF_ERR_BAD_PARAMETER);
629
630 (void) memset(&extn, 0, sizeof (extn));
631 ret = kmf_get_cert_extn(certdata,
632 (KMF_OID *)&KMFOID_CertificatePolicies, &extn);
633
634 if (ret != KMF_OK) {
635 goto end;
636 }
637
638 *critical = (extn.critical != 0);
639
640 /*
641 * Decode the ASN.1 data for the extension.
642 */
643 exdata.bv_val = (char *)extn.BERvalue.Data;
644 exdata.bv_len = extn.BERvalue.Length;
645
646 (void) memset((void *)extptr, 0, sizeof (KMF_X509EXT_CERT_POLICIES));
647
648 if ((asn1 = kmfder_init(&exdata)) == NULL) {
649 ret = KMF_ERR_MEMORY;
650 goto end;
651 }
652
653 /*
654 * certificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation
655 */
656 if ((tag = kmfber_first_element(asn1, &size, &end)) !=
657 BER_CONSTRUCTED_SEQUENCE) {
658 ret = KMF_ERR_BAD_CERT_FORMAT;
659 goto end;
660 }
661
662 /*
663 * Collect all of the PolicyInformation SEQUENCES
664 *
665 * PolicyInformation ::= SEQUENCE {
666 * policyIdentifier CertPolicyId,
667 * policyQualifiers SEQUENCE SIZE (1..MAX) OF
668 * PolicyQualifierInfo OPTIONAL
669 * }
670 *
671 * Loop over the SEQUENCES of PolicyInfo
672 */
673 while ((tag = kmfber_next_element(asn1, &size, end)) ==
674 BER_CONSTRUCTED_SEQUENCE) {
675
676 /* Skip over the CONSTRUCTED SET tag */
677 if (kmfber_scanf(asn1, "T", &tag) == KMFBER_DEFAULT) {
678 ret = KMF_ERR_BAD_CERT_FORMAT;
679 goto end;
680 }
681
682 pinfo = malloc(sizeof (KMF_X509EXT_POLICYINFO));
683 if (pinfo == NULL) {
684 ret = KMF_ERR_MEMORY;
685 goto end;
686 }
687 (void) memset((void *)pinfo, 0,
688 sizeof (KMF_X509EXT_POLICYINFO));
689 /*
690 * Decode the PolicyInformation SEQUENCE
691 */
692 if ((tag = kmfber_scanf(asn1, "D",
693 &pinfo->policyIdentifier)) == KMFBER_DEFAULT) {
694 ret = KMF_ERR_BAD_CERT_FORMAT;
695 goto end;
696 }
697 /*
698 * Gather all of the associated PolicyQualifierInfo recs
699 */
700 pqinfo = get_pqinfo(asn1);
701 if (pqinfo != NULL) {
702 int cnt =
703 pinfo->policyQualifiers.numberOfPolicyQualifiers;
704 cnt++;
705 pinfo->policyQualifiers.policyQualifier = realloc(
706 pinfo->policyQualifiers.policyQualifier,
707 cnt * sizeof (KMF_X509EXT_POLICYQUALIFIERINFO));
708 if (pinfo->policyQualifiers.policyQualifier == NULL) {
709 ret = KMF_ERR_MEMORY;
710 goto end;
711 }
712 pinfo->policyQualifiers.numberOfPolicyQualifiers = cnt;
713 pinfo->policyQualifiers.policyQualifier[cnt-1] =
714 *pqinfo;
715
716 free(pqinfo);
717 }
718 extptr->numberOfPolicyInfo++;
719 extptr->policyInfo = realloc(extptr->policyInfo,
720 extptr->numberOfPolicyInfo *
721 sizeof (KMF_X509EXT_POLICYINFO));
722 if (extptr->policyInfo == NULL) {
723 ret = KMF_ERR_MEMORY;
724 goto end;
725 }
726 extptr->policyInfo[extptr->numberOfPolicyInfo-1] = *pinfo;
727 free(pinfo);
728 }
729
730
731 end:
732 kmf_free_extn(&extn);
733 if (asn1 != NULL)
734 kmfber_free(asn1, 1);
735 return (ret);
736 }
737
738 /*
739 * If the given certificate data (X.509 DER encoded data)
740 * contains the Authority Information Access extension, parse that
741 * data and return it in the KMF_X509EXT_AUTHINFOACCESS
742 * record.
743 *
744 * RETURNS:
745 * KMF_OK - success
746 * KMF_ERR_BAD_PARAMETER - input data was bad.
747 * KMF_ERR_EXTENSION_NOT_FOUND - extension not found.
748 */
749 KMF_RETURN
kmf_get_cert_auth_info_access(const KMF_DATA * certdata,KMF_X509EXT_AUTHINFOACCESS * aia)750 kmf_get_cert_auth_info_access(const KMF_DATA *certdata,
751 KMF_X509EXT_AUTHINFOACCESS *aia)
752 {
753 KMF_RETURN ret = KMF_OK;
754 KMF_X509_EXTENSION extn;
755 BerElement *asn1 = NULL;
756 BerValue exdata;
757 ber_len_t size;
758 char *end = NULL;
759 int tag;
760 KMF_X509EXT_ACCESSDESC *access_info = NULL;
761
762 if (certdata == NULL || aia == NULL) {
763 return (KMF_ERR_BAD_PARAMETER);
764 }
765
766 (void) memset(&extn, 0, sizeof (KMF_X509_EXTENSION));
767 ret = kmf_get_cert_extn(certdata,
768 (KMF_OID *)&KMFOID_AuthorityInfoAccess, &extn);
769
770 if (ret != KMF_OK) {
771 goto end;
772 }
773
774 /*
775 * Decode the ASN.1 data for the extension.
776 */
777 exdata.bv_val = (char *)extn.BERvalue.Data;
778 exdata.bv_len = extn.BERvalue.Length;
779
780 (void) memset((void *)aia, 0, sizeof (KMF_X509EXT_AUTHINFOACCESS));
781
782 if ((asn1 = kmfder_init(&exdata)) == NULL) {
783 ret = KMF_ERR_MEMORY;
784 goto end;
785 }
786
787 /*
788 * AuthorityInfoAccessSyntax ::=
789 * SEQUENCE SIZE (1..MAX) OF AccessDescription
790 */
791 if ((tag = kmfber_first_element(asn1, &size, &end)) !=
792 BER_CONSTRUCTED_SEQUENCE) {
793 ret = KMF_ERR_BAD_CERT_FORMAT;
794 goto end;
795 }
796
797 /*
798 * AccessDescription ::= SEQUENCE {
799 * accessMethod OBJECT IDENTIFIER,
800 * accessLocation GeneralName }
801 */
802 while ((tag = kmfber_next_element(asn1, &size, end)) ==
803 BER_CONSTRUCTED_SEQUENCE) {
804
805 /* Skip over the CONSTRUCTED SET tag */
806 if (kmfber_scanf(asn1, "T", &tag) == KMFBER_DEFAULT) {
807 ret = KMF_ERR_BAD_CERT_FORMAT;
808 goto end;
809 }
810
811 access_info = malloc(sizeof (KMF_X509EXT_ACCESSDESC));
812 if (access_info == NULL) {
813 ret = KMF_ERR_MEMORY;
814 goto end;
815 }
816
817 (void) memset((void *)access_info, 0,
818 sizeof (KMF_X509EXT_ACCESSDESC));
819
820 /*
821 * Read the AccessMethod OID
822 */
823 if (kmfber_scanf(asn1, "D",
824 &access_info->AccessMethod) == KMFBER_DEFAULT) {
825 ret = KMF_ERR_BAD_CERT_FORMAT;
826 goto end;
827 }
828
829 /*
830 * The OID of the AccessMethod determines what
831 * sort of data comes next.
832 */
833 if (IsEqualOid(&access_info->AccessMethod,
834 (KMF_OID *)&KMFOID_PkixAdOcsp)) {
835 if (kmfber_scanf(asn1, "tl", &tag, &size) ==
836 KMFBER_DEFAULT || size == 0) {
837 ret = KMF_ERR_BAD_CERT_FORMAT;
838 goto end;
839 }
840
841 /*
842 * OCSP uri must be an IA5STRING or a GENNAME_URI
843 * with an implicit tag.
844 */
845 if (tag != BER_IA5STRING &&
846 tag != (0x80 | GENNAME_URI)) {
847 ret = KMF_ERR_BAD_CERT_FORMAT;
848 goto end;
849 }
850
851 if ((access_info->AccessLocation.Data =
852 malloc(size)) == NULL) {
853 ret = KMF_ERR_MEMORY;
854 goto end;
855 }
856
857 if (kmfber_scanf(asn1, "s",
858 access_info->AccessLocation.Data,
859 &access_info->AccessLocation.Length) ==
860 KMFBER_DEFAULT) {
861 ret = KMF_ERR_BAD_CERT_FORMAT;
862 goto end;
863 }
864 } else if (IsEqualOid(&access_info->AccessMethod,
865 (KMF_OID *)&KMFOID_PkixAdCaIssuers)) {
866 /* will be supported later with PKIX */
867 free(access_info);
868 access_info = NULL;
869 continue;
870 } else {
871 ret = KMF_ERR_BAD_CERT_FORMAT;
872 goto end;
873 }
874
875 aia->numberOfAccessDescription++;
876 aia->AccessDesc = realloc(aia->AccessDesc,
877 aia->numberOfAccessDescription *
878 sizeof (KMF_X509EXT_ACCESSDESC));
879
880 if (aia->AccessDesc == NULL) {
881 ret = KMF_ERR_MEMORY;
882 goto end;
883 }
884
885 aia->AccessDesc[aia->numberOfAccessDescription-1] =
886 *access_info;
887 free(access_info);
888 access_info = NULL;
889 }
890
891 end:
892 kmf_free_extn(&extn);
893 if (access_info != NULL)
894 free(access_info);
895 if (asn1 != NULL)
896 kmfber_free(asn1, 1);
897 return (ret);
898
899 }
900
901 /*
902 * This function parses the name portion of a der-encoded distribution point
903 * returns it in the KMF_CRL_DIST_POINT record.
904 *
905 * The "DistributionPointName" syntax is
906 *
907 * DistributionPointName ::= CHOICE {
908 * fullName [0] GeneralNames,
909 * nameRelativeToCRLIssuer [1] RelativeDistinguishedName }
910 *
911 * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GerneralName
912 *
913 * Note: for phase 1, we support fullName only.
914 */
915 static KMF_RETURN
parse_dp_name(char * dp_der_code,int dp_der_size,KMF_CRL_DIST_POINT * dp)916 parse_dp_name(char *dp_der_code, int dp_der_size, KMF_CRL_DIST_POINT *dp)
917 {
918 KMF_RETURN ret = KMF_OK;
919 char *url = NULL;
920 BerElement *asn1 = NULL;
921 BerValue ber_data;
922 ber_len_t size;
923 char *end = NULL;
924 int tag;
925 KMF_GENERALNAMES *fullname;
926
927 if (dp_der_code == NULL || dp_der_size == 0 || dp == NULL)
928 return (KMF_ERR_BAD_PARAMETER);
929
930 ber_data.bv_val = dp_der_code;
931 ber_data.bv_len = dp_der_size;
932 if ((asn1 = kmfder_init(&ber_data)) == NULL)
933 return (KMF_ERR_BAD_CERT_FORMAT);
934
935 tag = kmfber_first_element(asn1, &size, &end);
936 if (tag != 0xA0 && tag != 0xA1) {
937 ret = KMF_ERR_BAD_CERT_FORMAT;
938 goto out;
939 }
940
941 if (tag == 0xA0) { /* fullName */
942 dp->type = DP_GENERAL_NAME;
943
944 fullname = &(dp->name.full_name);
945 fullname->number = 0;
946
947 /* Skip over the explicit tag and size */
948 (void) kmfber_scanf(asn1, "T", &tag);
949
950 tag = kmfber_next_element(asn1, &size, end);
951 while (tag != KMFBER_DEFAULT &&
952 tag != KMFBER_END_OF_SEQORSET) {
953
954 if (kmfber_scanf(asn1, "tl", &tag, &size) ==
955 KMFBER_DEFAULT || size == 0) {
956 ret = KMF_ERR_BAD_CERT_FORMAT;
957 goto out;
958 }
959
960 /* For phase 1, we are interested in a URI name only */
961 if (tag != (0x80 | GENNAME_URI)) {
962 tag = kmfber_next_element(asn1, &size, end);
963 continue;
964 }
965
966 if ((url = malloc(size)) == NULL) {
967 ret = KMF_ERR_MEMORY;
968 goto out;
969 }
970
971 /* Skip type and len, then read url and save it. */
972 if (kmfber_read(asn1, url, 2) != 2) {
973 ret = KMF_ERR_BAD_CERT_FORMAT;
974 goto out;
975 }
976
977 if (kmfber_read(asn1, url, size) !=
978 (ber_slen_t)size) {
979 ret = KMF_ERR_BAD_CERT_FORMAT;
980 goto out;
981 }
982
983 fullname->number++;
984 fullname->namelist = realloc(fullname->namelist,
985 fullname->number * sizeof (KMF_GENERALNAME));
986 if (fullname->namelist == NULL) {
987 ret = KMF_ERR_MEMORY;
988 goto out;
989 }
990
991 fullname->namelist[fullname->number - 1].choice =
992 GENNAME_URI;
993 fullname->namelist[fullname->number - 1].name.Length =
994 size;
995 fullname->namelist[fullname->number - 1].name.Data =
996 (unsigned char *)url;
997
998 /* next */
999 tag = kmfber_next_element(asn1, &size, end);
1000 }
1001
1002 } else if (tag == 0xA1) {
1003 /* "nameRelativeToCRLIssuer" is not supported at phase 1. */
1004 ret = KMF_ERR_BAD_CERT_FORMAT;
1005 goto out;
1006 }
1007
1008 out:
1009 if (asn1 != NULL)
1010 kmfber_free(asn1, 1);
1011
1012 if (ret != KMF_OK) {
1013 free_dp_name(dp);
1014 }
1015
1016 if (ret == KMF_OK && fullname->number == 0) {
1017 ret = KMF_ERR_EXTENSION_NOT_FOUND;
1018 if (url != NULL)
1019 free(url);
1020 }
1021
1022 return (ret);
1023 }
1024
1025 /*
1026 * This function retrieves the CRL Distribution Points extension data from
1027 * a DER encoded certificate if it contains this extension, parses the
1028 * extension data, and returns it in the KMF_X509EXT_CRLDISTPOINTS record.
1029 */
1030 KMF_RETURN
kmf_get_cert_crl_dist_pts(const KMF_DATA * certdata,KMF_X509EXT_CRLDISTPOINTS * crl_dps)1031 kmf_get_cert_crl_dist_pts(const KMF_DATA *certdata,
1032 KMF_X509EXT_CRLDISTPOINTS *crl_dps)
1033 {
1034 KMF_RETURN ret = KMF_OK;
1035 KMF_X509_EXTENSION extn;
1036 BerElement *asn1 = NULL;
1037 BerValue exdata;
1038 ber_len_t size;
1039 char *end = NULL;
1040 int tag;
1041 KMF_CRL_DIST_POINT *dp = NULL;
1042 int i;
1043
1044 if (certdata == NULL || crl_dps == NULL) {
1045 return (KMF_ERR_BAD_PARAMETER);
1046 }
1047
1048 /* Get the ASN.1 data for this extension. */
1049 (void) memset(&extn, 0, sizeof (KMF_X509_EXTENSION));
1050 ret = kmf_get_cert_extn(certdata,
1051 (KMF_OID *)&KMFOID_CrlDistributionPoints, &extn);
1052 if (ret != KMF_OK) {
1053 return (ret);
1054 }
1055
1056 /*
1057 * Decode the CRLDistributionPoints ASN.1 data. The Syntax for
1058 * CRLDistributionPoints is
1059 *
1060 * CRLDistributionPoints ::=
1061 * SEQUENCE SIZE (1..MAX) OF DistributionPoint
1062 *
1063 * DistributionPoint ::= SEQUENCE {
1064 * distributionPoint [0] DistributionPointName OPTIONAL,
1065 * reasons [1] ReasonFlags OPTIONAL,
1066 * cRLIssuer [2] GeneralNames OPTIONAL }
1067 */
1068
1069 exdata.bv_val = (char *)extn.BERvalue.Data;
1070 exdata.bv_len = extn.BERvalue.Length;
1071 if ((asn1 = kmfder_init(&exdata)) == NULL) {
1072 ret = KMF_ERR_MEMORY;
1073 goto out;
1074 }
1075
1076 if ((tag = kmfber_first_element(asn1, &size, &end)) !=
1077 BER_CONSTRUCTED_SEQUENCE) {
1078 ret = KMF_ERR_BAD_CERT_FORMAT;
1079 goto out;
1080 }
1081
1082 (void) memset((void *)crl_dps, 0, sizeof (KMF_X509EXT_CRLDISTPOINTS));
1083
1084 while ((tag = kmfber_next_element(asn1, &size, end)) ==
1085 BER_CONSTRUCTED_SEQUENCE) {
1086 boolean_t has_name = B_FALSE;
1087 boolean_t has_issuer = B_FALSE;
1088
1089 /* Skip over the CONSTRUCTED SET tag */
1090 if (kmfber_scanf(asn1, "T", &tag) == KMFBER_DEFAULT) {
1091 ret = KMF_ERR_BAD_CERT_FORMAT;
1092 goto out;
1093 }
1094
1095 tag = kmfber_next_element(asn1, &size, end);
1096 if (tag != 0xA0 && tag != 0xA1 && tag != 0xA2)
1097 goto out;
1098
1099 if ((dp = malloc(sizeof (KMF_CRL_DIST_POINT))) == NULL) {
1100 ret = KMF_ERR_MEMORY;
1101 goto out;
1102 }
1103 (void) memset((void *)dp, 0, sizeof (KMF_CRL_DIST_POINT));
1104
1105 if (tag == 0xA0) { /* distributionPoint Name */
1106 char *name_der;
1107 int name_size = size + 2;
1108
1109 if ((name_der = malloc(name_size)) == NULL) {
1110 ret = KMF_ERR_MEMORY;
1111 free(dp);
1112 dp = NULL;
1113 goto out;
1114 }
1115
1116 if (kmfber_read(asn1, name_der, name_size) !=
1117 (ber_slen_t)(name_size)) {
1118 ret = KMF_ERR_BAD_CERT_FORMAT;
1119 free(name_der);
1120 free(dp);
1121 dp = NULL;
1122 goto out;
1123 }
1124 has_name = B_TRUE;
1125
1126 ret = parse_dp_name(name_der, name_size, dp);
1127 free(name_der);
1128 if (ret != KMF_OK) {
1129 free(dp);
1130 dp = NULL;
1131 goto out;
1132 }
1133
1134 /* next field */
1135 tag = kmfber_next_element(asn1, &size, end);
1136 }
1137
1138 if (tag == 0XA1) { /* reasons */
1139 char *bit_string;
1140 int len;
1141
1142 if (kmfber_scanf(asn1, "B", &bit_string, &len) !=
1143 BER_BIT_STRING) {
1144 ret = KMF_ERR_BAD_CERT_FORMAT;
1145 free(dp);
1146 dp = NULL;
1147 goto out;
1148 }
1149
1150 dp->reasons.Length = len / 8;
1151 if ((dp->reasons.Data = malloc(dp->reasons.Length)) ==
1152 NULL) {
1153 ret = KMF_ERR_MEMORY;
1154 free(dp);
1155 dp = NULL;
1156 goto out;
1157 }
1158 (void) memcpy(dp->reasons.Data, (uchar_t *)bit_string,
1159 dp->reasons.Length);
1160
1161 /* next field */
1162 tag = kmfber_next_element(asn1, &size, end);
1163 }
1164
1165 if (tag == 0XA2) { /* cRLIssuer */
1166 char *issuer_der = NULL;
1167 int issuer_size;
1168
1169 /* For cRLIssuer, read the data only at phase 1 */
1170 issuer_size = size + 2;
1171 issuer_der = malloc(issuer_size);
1172 if (issuer_der == NULL) {
1173 ret = KMF_ERR_MEMORY;
1174 free(dp);
1175 dp = NULL;
1176 goto out;
1177 }
1178
1179 if (kmfber_read(asn1, issuer_der, issuer_size) !=
1180 (ber_slen_t)(issuer_size)) {
1181 free(issuer_der);
1182 ret = KMF_ERR_BAD_CERT_FORMAT;
1183 free(dp);
1184 dp = NULL;
1185 goto out;
1186 }
1187
1188 has_issuer = B_TRUE;
1189 free(issuer_der);
1190 }
1191
1192 /* A distribution point cannot have a "reasons" field only. */
1193 if (has_name == B_FALSE && has_issuer == B_FALSE) {
1194 ret = KMF_ERR_BAD_CERT_FORMAT;
1195 free_dp(dp);
1196 free(dp);
1197 dp = NULL;
1198 goto out;
1199 }
1200
1201 /*
1202 * Although it is legal that a distributioon point contains
1203 * a cRLIssuer field only, with or without "reasons", we will
1204 * skip it if the name field is not presented for phase 1.
1205 */
1206 if (has_name == B_FALSE) {
1207 free_dp(dp);
1208 } else {
1209 crl_dps->number++;
1210 crl_dps->dplist = realloc(crl_dps->dplist,
1211 crl_dps->number * sizeof (KMF_CRL_DIST_POINT));
1212 if (crl_dps->dplist == NULL) {
1213 ret = KMF_ERR_MEMORY;
1214 free_dp(dp);
1215 free(dp);
1216 dp = NULL;
1217 goto out;
1218 }
1219 crl_dps->dplist[crl_dps->number - 1] = *dp;
1220 /* free the dp itself since we just used its contents */
1221 }
1222 if (dp != NULL) {
1223 free(dp);
1224 dp = NULL;
1225 }
1226 }
1227
1228 out:
1229 kmf_free_extn(&extn);
1230
1231 if (asn1 != NULL)
1232 kmfber_free(asn1, 1);
1233
1234 if (ret != KMF_OK) {
1235 for (i = 0; i < crl_dps->number; i++)
1236 free_dp(&(crl_dps->dplist[i]));
1237 free(crl_dps->dplist);
1238 }
1239
1240 if (ret == KMF_OK && crl_dps->number == 0) {
1241 ret = KMF_ERR_BAD_CERT_FORMAT;
1242 }
1243
1244 return (ret);
1245 }
1246
1247 static KMF_RETURN
KMF_CertGetPrintable(KMF_HANDLE_T handle,const KMF_DATA * SignedCert,KMF_PRINTABLE_ITEM flag,char * resultStr)1248 KMF_CertGetPrintable(KMF_HANDLE_T handle, const KMF_DATA *SignedCert,
1249 KMF_PRINTABLE_ITEM flag, char *resultStr)
1250 {
1251 KMF_PLUGIN *plugin;
1252 KMF_RETURN (*getPrintableFn)(void *, const KMF_DATA *,
1253 KMF_PRINTABLE_ITEM, char *);
1254 KMF_RETURN ret;
1255
1256 CLEAR_ERROR(handle, ret);
1257 if (ret != KMF_OK)
1258 return (ret);
1259
1260 if (SignedCert == NULL || resultStr == NULL) {
1261 return (KMF_ERR_BAD_PARAMETER);
1262 }
1263
1264 /*
1265 * This framework function is actually implemented in the openssl
1266 * plugin library, so we find the function address and call it.
1267 */
1268 plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL);
1269 if (plugin == NULL || plugin->dldesc == NULL) {
1270 return (KMF_ERR_PLUGIN_NOTFOUND);
1271 }
1272
1273 getPrintableFn = (KMF_RETURN(*)())dlsym(plugin->dldesc,
1274 "OpenSSL_CertGetPrintable");
1275 if (getPrintableFn == NULL) {
1276 return (KMF_ERR_FUNCTION_NOT_FOUND);
1277 }
1278
1279 return (getPrintableFn(handle, SignedCert, flag, resultStr));
1280 }
1281
1282 KMF_RETURN
kmf_get_cert_version_str(KMF_HANDLE_T handle,const KMF_DATA * SignedCert,char ** result)1283 kmf_get_cert_version_str(KMF_HANDLE_T handle, const KMF_DATA *SignedCert,
1284 char **result)
1285 {
1286 KMF_RETURN ret;
1287 char *tmpstr;
1288
1289 CLEAR_ERROR(handle, ret);
1290 if (ret != KMF_OK)
1291 return (ret);
1292
1293 if (SignedCert == NULL || result == NULL)
1294 return (KMF_ERR_BAD_PARAMETER);
1295 tmpstr = malloc(KMF_CERT_PRINTABLE_LEN);
1296 if (tmpstr == NULL)
1297 return (KMF_ERR_MEMORY);
1298 (void) memset(tmpstr, 0, KMF_CERT_PRINTABLE_LEN);
1299
1300 ret = KMF_CertGetPrintable(handle, SignedCert, KMF_CERT_VERSION,
1301 tmpstr);
1302
1303 if (ret == KMF_OK) {
1304 *result = tmpstr;
1305 } else {
1306 free(tmpstr);
1307 *result = NULL;
1308 }
1309
1310 return (ret);
1311 }
1312
1313
1314 KMF_RETURN
kmf_get_cert_subject_str(KMF_HANDLE_T handle,const KMF_DATA * SignedCert,char ** result)1315 kmf_get_cert_subject_str(KMF_HANDLE_T handle, const KMF_DATA *SignedCert,
1316 char **result)
1317 {
1318 KMF_RETURN ret;
1319 char *tmpstr;
1320
1321 CLEAR_ERROR(handle, ret);
1322 if (ret != KMF_OK)
1323 return (ret);
1324
1325 if (SignedCert == NULL || result == NULL)
1326 return (KMF_ERR_BAD_PARAMETER);
1327 tmpstr = malloc(KMF_CERT_PRINTABLE_LEN);
1328 if (tmpstr == NULL)
1329 return (KMF_ERR_MEMORY);
1330 (void) memset(tmpstr, 0, KMF_CERT_PRINTABLE_LEN);
1331
1332 ret = KMF_CertGetPrintable(handle, SignedCert, KMF_CERT_SUBJECT,
1333 tmpstr);
1334
1335 if (ret == KMF_OK) {
1336 *result = tmpstr;
1337 } else {
1338 free(tmpstr);
1339 *result = NULL;
1340 }
1341
1342 return (ret);
1343
1344 }
1345
1346 KMF_RETURN
kmf_get_cert_issuer_str(KMF_HANDLE_T handle,const KMF_DATA * SignedCert,char ** result)1347 kmf_get_cert_issuer_str(KMF_HANDLE_T handle, const KMF_DATA *SignedCert,
1348 char **result)
1349 {
1350 KMF_RETURN ret;
1351 char *tmpstr;
1352
1353 CLEAR_ERROR(handle, ret);
1354 if (ret != KMF_OK)
1355 return (ret);
1356
1357 if (SignedCert == NULL || result == NULL)
1358 return (KMF_ERR_BAD_PARAMETER);
1359
1360 tmpstr = malloc(KMF_CERT_PRINTABLE_LEN);
1361 if (tmpstr == NULL)
1362 return (KMF_ERR_MEMORY);
1363 (void) memset(tmpstr, 0, KMF_CERT_PRINTABLE_LEN);
1364
1365 ret = KMF_CertGetPrintable(handle, SignedCert, KMF_CERT_ISSUER,
1366 tmpstr);
1367
1368 if (ret == KMF_OK) {
1369 *result = tmpstr;
1370 } else {
1371 free(tmpstr);
1372 *result = NULL;
1373 }
1374
1375 return (ret);
1376 }
1377
1378 KMF_RETURN
kmf_get_cert_serial_str(KMF_HANDLE_T handle,const KMF_DATA * SignedCert,char ** result)1379 kmf_get_cert_serial_str(KMF_HANDLE_T handle, const KMF_DATA *SignedCert,
1380 char **result)
1381 {
1382 KMF_RETURN ret;
1383 char *tmpstr;
1384
1385 CLEAR_ERROR(handle, ret);
1386 if (ret != KMF_OK)
1387 return (ret);
1388
1389 if (SignedCert == NULL || result == NULL)
1390 return (KMF_ERR_BAD_PARAMETER);
1391 tmpstr = malloc(KMF_CERT_PRINTABLE_LEN);
1392 if (tmpstr == NULL)
1393 return (KMF_ERR_MEMORY);
1394 (void) memset(tmpstr, 0, KMF_CERT_PRINTABLE_LEN);
1395
1396 ret = KMF_CertGetPrintable(handle, SignedCert, KMF_CERT_SERIALNUM,
1397 tmpstr);
1398
1399 if (ret == KMF_OK) {
1400 *result = tmpstr;
1401 } else {
1402 free(tmpstr);
1403 *result = NULL;
1404 }
1405
1406 return (ret);
1407 }
1408
1409 KMF_RETURN
kmf_get_cert_start_date_str(KMF_HANDLE_T handle,const KMF_DATA * SignedCert,char ** result)1410 kmf_get_cert_start_date_str(KMF_HANDLE_T handle, const KMF_DATA *SignedCert,
1411 char **result)
1412 {
1413 KMF_RETURN ret;
1414 char *tmpstr;
1415
1416 CLEAR_ERROR(handle, ret);
1417 if (ret != KMF_OK)
1418 return (ret);
1419
1420 if (SignedCert == NULL || result == NULL)
1421 return (KMF_ERR_BAD_PARAMETER);
1422 tmpstr = malloc(KMF_CERT_PRINTABLE_LEN);
1423 if (tmpstr == NULL)
1424 return (KMF_ERR_MEMORY);
1425 (void) memset(tmpstr, 0, KMF_CERT_PRINTABLE_LEN);
1426
1427 ret = KMF_CertGetPrintable(handle, SignedCert, KMF_CERT_NOTBEFORE,
1428 tmpstr);
1429
1430 if (ret == KMF_OK) {
1431 *result = tmpstr;
1432 } else {
1433 free(tmpstr);
1434 *result = NULL;
1435 }
1436
1437 return (ret);
1438 }
1439
1440 KMF_RETURN
kmf_get_cert_end_date_str(KMF_HANDLE_T handle,const KMF_DATA * SignedCert,char ** result)1441 kmf_get_cert_end_date_str(KMF_HANDLE_T handle, const KMF_DATA *SignedCert,
1442 char **result)
1443 {
1444 KMF_RETURN ret;
1445 char *tmpstr;
1446
1447 CLEAR_ERROR(handle, ret);
1448 if (ret != KMF_OK)
1449 return (ret);
1450
1451 if (SignedCert == NULL || result == NULL)
1452 return (KMF_ERR_BAD_PARAMETER);
1453 tmpstr = malloc(KMF_CERT_PRINTABLE_LEN);
1454 if (tmpstr == NULL)
1455 return (KMF_ERR_MEMORY);
1456 (void) memset(tmpstr, 0, KMF_CERT_PRINTABLE_LEN);
1457
1458 ret = KMF_CertGetPrintable(handle, SignedCert, KMF_CERT_NOTAFTER,
1459 tmpstr);
1460
1461 if (ret == KMF_OK) {
1462 *result = tmpstr;
1463 } else {
1464 free(tmpstr);
1465 *result = NULL;
1466 }
1467
1468 return (ret);
1469 }
1470
1471 KMF_RETURN
kmf_get_cert_pubkey_alg_str(KMF_HANDLE_T handle,const KMF_DATA * SignedCert,char ** result)1472 kmf_get_cert_pubkey_alg_str(KMF_HANDLE_T handle, const KMF_DATA *SignedCert,
1473 char **result)
1474 {
1475 KMF_RETURN ret;
1476 char *tmpstr;
1477
1478 CLEAR_ERROR(handle, ret);
1479 if (ret != KMF_OK)
1480 return (ret);
1481
1482 if (SignedCert == NULL || result == NULL)
1483 return (KMF_ERR_BAD_PARAMETER);
1484 tmpstr = malloc(KMF_CERT_PRINTABLE_LEN);
1485 if (tmpstr == NULL)
1486 return (KMF_ERR_MEMORY);
1487 (void) memset(tmpstr, 0, KMF_CERT_PRINTABLE_LEN);
1488
1489 ret = KMF_CertGetPrintable(handle, SignedCert, KMF_CERT_PUBKEY_ALG,
1490 tmpstr);
1491
1492 if (ret == KMF_OK) {
1493 *result = tmpstr;
1494 } else {
1495 free(tmpstr);
1496 *result = NULL;
1497 }
1498
1499 return (ret);
1500 }
1501
1502 KMF_RETURN
kmf_get_cert_sig_alg_str(KMF_HANDLE_T handle,const KMF_DATA * SignedCert,char ** result)1503 kmf_get_cert_sig_alg_str(KMF_HANDLE_T handle, const KMF_DATA *SignedCert,
1504 char **result)
1505 {
1506 KMF_RETURN ret;
1507 char *tmpstr;
1508
1509 CLEAR_ERROR(handle, ret);
1510 if (ret != KMF_OK)
1511 return (ret);
1512
1513 if (SignedCert == NULL || result == NULL)
1514 return (KMF_ERR_BAD_PARAMETER);
1515 tmpstr = malloc(KMF_CERT_PRINTABLE_LEN);
1516 if (tmpstr == NULL)
1517 return (KMF_ERR_MEMORY);
1518 (void) memset(tmpstr, 0, KMF_CERT_PRINTABLE_LEN);
1519
1520 ret = KMF_CertGetPrintable(handle, SignedCert, KMF_CERT_SIGNATURE_ALG,
1521 tmpstr);
1522
1523 if (ret == KMF_OK) {
1524 *result = tmpstr;
1525 } else {
1526 free(tmpstr);
1527 *result = NULL;
1528 }
1529
1530 return (ret);
1531 }
1532
1533 KMF_RETURN
kmf_get_cert_pubkey_str(KMF_HANDLE_T handle,const KMF_DATA * SignedCert,char ** result)1534 kmf_get_cert_pubkey_str(KMF_HANDLE_T handle, const KMF_DATA *SignedCert,
1535 char **result)
1536 {
1537 KMF_RETURN ret;
1538 char *tmpstr;
1539
1540 CLEAR_ERROR(handle, ret);
1541 if (ret != KMF_OK)
1542 return (ret);
1543
1544 if (SignedCert == NULL || result == NULL)
1545 return (KMF_ERR_BAD_PARAMETER);
1546 tmpstr = malloc(KMF_CERT_PRINTABLE_LEN);
1547 if (tmpstr == NULL)
1548 return (KMF_ERR_MEMORY);
1549 (void) memset(tmpstr, 0, KMF_CERT_PRINTABLE_LEN);
1550
1551 ret = KMF_CertGetPrintable(handle, SignedCert, KMF_CERT_PUBKEY_DATA,
1552 tmpstr);
1553
1554 if (ret == KMF_OK) {
1555 *result = tmpstr;
1556 } else {
1557 free(tmpstr);
1558 *result = NULL;
1559 }
1560
1561 return (ret);
1562 }
1563
1564 KMF_RETURN
kmf_get_cert_email_str(KMF_HANDLE_T handle,const KMF_DATA * SignedCert,char ** result)1565 kmf_get_cert_email_str(KMF_HANDLE_T handle, const KMF_DATA *SignedCert,
1566 char **result)
1567 {
1568 KMF_RETURN ret;
1569 char *tmpstr;
1570
1571 CLEAR_ERROR(handle, ret);
1572 if (ret != KMF_OK)
1573 return (ret);
1574
1575 if (SignedCert == NULL || result == NULL)
1576 return (KMF_ERR_BAD_PARAMETER);
1577 tmpstr = malloc(KMF_CERT_PRINTABLE_LEN);
1578 if (tmpstr == NULL)
1579 return (KMF_ERR_MEMORY);
1580 (void) memset(tmpstr, 0, KMF_CERT_PRINTABLE_LEN);
1581
1582 ret = KMF_CertGetPrintable(handle, SignedCert, KMF_CERT_EMAIL, tmpstr);
1583
1584 if (ret == KMF_OK) {
1585 *result = tmpstr;
1586 } else {
1587 free(tmpstr);
1588 *result = NULL;
1589 }
1590
1591 return (ret);
1592 }
1593
1594 /*
1595 * Given a certificate (DER Encoded data) and a KMF
1596 * extension identifier constant (e.g. KMF_X509_EXT_*),
1597 * return a human readable interpretation of the
1598 * extension data.
1599 *
1600 * The string will be a maximum of KMF_CERT_PRINTABLE_LEN
1601 * bytes long. The string is allocated locally and
1602 * must be freed by the caller.
1603 */
1604 KMF_RETURN
kmf_get_cert_extn_str(KMF_HANDLE_T handle,const KMF_DATA * cert,KMF_PRINTABLE_ITEM extension,char ** result)1605 kmf_get_cert_extn_str(KMF_HANDLE_T handle, const KMF_DATA *cert,
1606 KMF_PRINTABLE_ITEM extension, char **result)
1607 {
1608 KMF_RETURN ret;
1609 char *tmpstr;
1610
1611 CLEAR_ERROR(handle, ret);
1612 if (ret != KMF_OK)
1613 return (ret);
1614
1615 if (cert == NULL || result == NULL)
1616 return (KMF_ERR_BAD_PARAMETER);
1617
1618 tmpstr = malloc(KMF_CERT_PRINTABLE_LEN);
1619 if (tmpstr == NULL)
1620 return (KMF_ERR_MEMORY);
1621 (void) memset(tmpstr, 0, KMF_CERT_PRINTABLE_LEN);
1622
1623 ret = KMF_CertGetPrintable(handle, cert, extension, tmpstr);
1624
1625 if (ret == KMF_OK) {
1626 *result = tmpstr;
1627 } else {
1628 free(tmpstr);
1629 *result = NULL;
1630 }
1631
1632 return (ret);
1633 }
1634
1635 KMF_RETURN
kmf_get_cert_id_data(const KMF_DATA * SignedCert,KMF_DATA * ID)1636 kmf_get_cert_id_data(const KMF_DATA *SignedCert, KMF_DATA *ID)
1637 {
1638 KMF_RETURN ret;
1639 KMF_X509_CERTIFICATE *cert = NULL;
1640
1641 if (SignedCert == NULL || ID == NULL)
1642 return (KMF_ERR_BAD_PARAMETER);
1643
1644 ret = DerDecodeSignedCertificate(SignedCert, &cert);
1645 if (ret != KMF_OK)
1646 return (ret);
1647
1648 ret = GetIDFromSPKI(&cert->certificate.subjectPublicKeyInfo, ID);
1649
1650 kmf_free_signed_cert(cert);
1651 free(cert);
1652 return (ret);
1653 }
1654
1655 KMF_RETURN
kmf_get_cert_id_str(const KMF_DATA * SignedCert,char ** idstr)1656 kmf_get_cert_id_str(const KMF_DATA *SignedCert, char **idstr)
1657 {
1658 KMF_RETURN ret;
1659 KMF_DATA ID = { 0, NULL };
1660 char tmpstr[256];
1661 int i;
1662
1663 if (SignedCert == NULL || idstr == NULL)
1664 return (KMF_ERR_BAD_PARAMETER);
1665
1666 ret = kmf_get_cert_id_data(SignedCert, &ID);
1667 if (ret != KMF_OK) {
1668 kmf_free_data(&ID);
1669 return (ret);
1670 }
1671
1672 (void) memset(tmpstr, 0, sizeof (tmpstr));
1673 for (i = 0; i < ID.Length; i++) {
1674 int len = strlen(tmpstr);
1675 (void) snprintf(&tmpstr[len], sizeof (tmpstr) - len,
1676 "%02x", (uchar_t)ID.Data[i]);
1677 if ((i+1) < ID.Length)
1678 (void) strcat(tmpstr, ":");
1679 }
1680 *idstr = strdup(tmpstr);
1681 if ((*idstr) == NULL)
1682 ret = KMF_ERR_MEMORY;
1683
1684 kmf_free_data(&ID);
1685
1686 return (ret);
1687 }
1688
1689
1690 /*
1691 * This function gets the time_t values of the notbefore and notafter dates
1692 * from a der-encoded certificate.
1693 */
1694 KMF_RETURN
kmf_get_cert_validity(const KMF_DATA * cert,time_t * not_before,time_t * not_after)1695 kmf_get_cert_validity(const KMF_DATA *cert, time_t *not_before,
1696 time_t *not_after)
1697 {
1698 KMF_RETURN rv = KMF_OK;
1699 KMF_X509_CERTIFICATE *certData = NULL;
1700 struct tm tm_tmp;
1701 time_t t_notbefore;
1702 time_t t_notafter;
1703 unsigned char *not_before_str;
1704 unsigned char *not_after_str;
1705
1706 if (cert == NULL || not_before == NULL || not_after == NULL)
1707 return (KMF_ERR_BAD_PARAMETER);
1708
1709 rv = DerDecodeSignedCertificate(cert, &certData);
1710 if (rv != KMF_OK)
1711 return (rv);
1712
1713 /* Get notBefore */
1714 not_before_str = certData->certificate.validity.notBefore.time.Data;
1715 if (strptime((const char *)not_before_str, "%y %m %d %H %M %S",
1716 &tm_tmp) == NULL) {
1717 rv = KMF_ERR_VALIDITY_PERIOD;
1718 goto out;
1719 }
1720
1721 errno = 0;
1722 if (((t_notbefore = mktime(&tm_tmp)) == (time_t)(-1)) &&
1723 errno == EOVERFLOW) {
1724 rv = KMF_ERR_VALIDITY_PERIOD;
1725 goto out;
1726 }
1727 *not_before = t_notbefore;
1728
1729 /* Get notAfter */
1730 not_after_str = certData->certificate.validity.notAfter.time.Data;
1731 if (strptime((const char *)not_after_str, "%y %m %d %H %M %S",
1732 &tm_tmp) == NULL) {
1733 rv = KMF_ERR_VALIDITY_PERIOD;
1734 goto out;
1735 }
1736
1737 errno = 0;
1738 if (((t_notafter = mktime(&tm_tmp)) == (time_t)(-1)) &&
1739 errno == EOVERFLOW) {
1740 rv = KMF_ERR_VALIDITY_PERIOD;
1741 goto out;
1742 }
1743 *not_after = t_notafter;
1744
1745 out:
1746 if (certData != NULL) {
1747 kmf_free_signed_cert(certData);
1748 free(certData);
1749 }
1750
1751 return (rv);
1752 }
1753
1754 KMF_RETURN
kmf_set_cert_pubkey(KMF_HANDLE_T handle,KMF_KEY_HANDLE * KMFKey,KMF_X509_CERTIFICATE * Cert)1755 kmf_set_cert_pubkey(KMF_HANDLE_T handle,
1756 KMF_KEY_HANDLE *KMFKey,
1757 KMF_X509_CERTIFICATE *Cert)
1758 {
1759 KMF_RETURN ret = KMF_OK;
1760 KMF_X509_SPKI *spki_ptr;
1761 KMF_PLUGIN *plugin;
1762 KMF_DATA KeyData = { 0, NULL };
1763
1764 CLEAR_ERROR(handle, ret);
1765 if (ret != KMF_OK)
1766 return (ret);
1767
1768 if (KMFKey == NULL || Cert == NULL) {
1769 return (KMF_ERR_BAD_PARAMETER);
1770 }
1771
1772 /* The keystore must extract the pubkey data */
1773 plugin = FindPlugin(handle, KMFKey->kstype);
1774 if (plugin != NULL && plugin->funclist->EncodePubkeyData != NULL) {
1775 ret = plugin->funclist->EncodePubkeyData(handle,
1776 KMFKey, &KeyData);
1777 } else {
1778 return (KMF_ERR_PLUGIN_NOTFOUND);
1779 }
1780
1781 spki_ptr = &Cert->certificate.subjectPublicKeyInfo;
1782
1783 if (KeyData.Data != NULL) {
1784 ret = DerDecodeSPKI(&KeyData, spki_ptr);
1785 free(KeyData.Data);
1786 }
1787
1788 return (ret);
1789 }
1790
1791 KMF_RETURN
kmf_set_cert_subject(KMF_X509_CERTIFICATE * CertData,KMF_X509_NAME * subject_name_ptr)1792 kmf_set_cert_subject(KMF_X509_CERTIFICATE *CertData,
1793 KMF_X509_NAME *subject_name_ptr)
1794 {
1795
1796 KMF_RETURN rv = KMF_OK;
1797 KMF_X509_NAME *temp_name_ptr = NULL;
1798
1799 if (CertData != NULL && subject_name_ptr != NULL) {
1800 rv = CopyRDN(subject_name_ptr, &temp_name_ptr);
1801 if (rv == KMF_OK) {
1802 CertData->certificate.subject = *temp_name_ptr;
1803 }
1804 } else {
1805 return (KMF_ERR_BAD_PARAMETER);
1806 }
1807 return (rv);
1808 }
1809
1810 KMF_RETURN
set_key_usage_extension(KMF_X509_EXTENSIONS * extns,int critical,uint32_t bits)1811 set_key_usage_extension(KMF_X509_EXTENSIONS *extns,
1812 int critical, uint32_t bits)
1813 {
1814 KMF_RETURN ret = KMF_OK;
1815 KMF_X509_EXTENSION extn;
1816 BerElement *asn1 = NULL;
1817 BerValue *extdata;
1818 int bitlen, i;
1819 uint16_t kubits = (uint16_t)(bits & 0x0000ffff);
1820
1821 if (extns == NULL)
1822 return (KMF_ERR_BAD_PARAMETER);
1823
1824 (void) memset(&extn, 0, sizeof (extn));
1825 ret = copy_data(&extn.extnId, (KMF_OID *)&KMFOID_KeyUsage);
1826 if (ret != KMF_OK)
1827 return (ret);
1828 extn.critical = critical;
1829 extn.format = KMF_X509_DATAFORMAT_ENCODED;
1830
1831 for (i = 7; i <= 15 && !(kubits & (1 << i)); i++)
1832 /* empty body */
1833 ;
1834
1835 bitlen = 16 - i;
1836
1837 if ((asn1 = kmfder_alloc()) == NULL)
1838 return (KMF_ERR_MEMORY);
1839
1840 kubits = htons(kubits);
1841 if (kmfber_printf(asn1, "B", (char *)&kubits, bitlen) == -1) {
1842 ret = KMF_ERR_ENCODING;
1843 goto out;
1844 }
1845 if (kmfber_flatten(asn1, &extdata) == -1) {
1846 ret = KMF_ERR_ENCODING;
1847 goto out;
1848 }
1849
1850 extn.BERvalue.Data = (uchar_t *)extdata->bv_val;
1851 extn.BERvalue.Length = extdata->bv_len;
1852
1853 free(extdata);
1854
1855 ret = add_an_extension(extns, &extn);
1856 if (ret != KMF_OK) {
1857 free(extn.BERvalue.Data);
1858 }
1859 out:
1860 if (asn1 != NULL)
1861 kmfber_free(asn1, 1);
1862
1863 return (ret);
1864 }
1865
1866 KMF_RETURN
kmf_set_cert_ku(KMF_X509_CERTIFICATE * CertData,int critical,uint16_t kubits)1867 kmf_set_cert_ku(KMF_X509_CERTIFICATE *CertData,
1868 int critical, uint16_t kubits)
1869 {
1870 KMF_RETURN ret = KMF_OK;
1871
1872 if (CertData == NULL)
1873 return (KMF_ERR_BAD_PARAMETER);
1874
1875 ret = set_key_usage_extension(&CertData->certificate.extensions,
1876 critical, kubits);
1877
1878 return (ret);
1879 }
1880
1881 KMF_RETURN
kmf_set_cert_issuer(KMF_X509_CERTIFICATE * CertData,KMF_X509_NAME * issuer_name_ptr)1882 kmf_set_cert_issuer(KMF_X509_CERTIFICATE *CertData,
1883 KMF_X509_NAME *issuer_name_ptr)
1884 {
1885
1886 KMF_RETURN rv = KMF_OK;
1887 KMF_X509_NAME *temp_name_ptr = NULL;
1888
1889 if (CertData != NULL && issuer_name_ptr != NULL) {
1890 rv = CopyRDN(issuer_name_ptr, &temp_name_ptr);
1891 if (rv == KMF_OK) {
1892 CertData->certificate.issuer = *temp_name_ptr;
1893 }
1894 } else {
1895 return (KMF_ERR_BAD_PARAMETER);
1896 }
1897
1898 return (rv);
1899 }
1900
1901 KMF_RETURN
kmf_set_cert_sig_alg(KMF_X509_CERTIFICATE * CertData,KMF_ALGORITHM_INDEX sigAlg)1902 kmf_set_cert_sig_alg(KMF_X509_CERTIFICATE *CertData,
1903 KMF_ALGORITHM_INDEX sigAlg)
1904 {
1905 KMF_OID *alg;
1906
1907 if (CertData == NULL)
1908 return (KMF_ERR_BAD_PARAMETER);
1909
1910 alg = x509_algid_to_algoid(sigAlg);
1911
1912 if (alg != NULL) {
1913 (void) copy_data((KMF_DATA *)
1914 &CertData->certificate.signature.algorithm,
1915 (KMF_DATA *)alg);
1916 (void) copy_data(&CertData->certificate.signature.parameters,
1917 &CertData->certificate.subjectPublicKeyInfo.algorithm.
1918 parameters);
1919
1920 (void) copy_data(
1921 &CertData->signature.algorithmIdentifier.algorithm,
1922 &CertData->certificate.signature.algorithm);
1923 (void) copy_data(
1924 &CertData->signature.algorithmIdentifier.parameters,
1925 &CertData->certificate.signature.parameters);
1926 } else {
1927 return (KMF_ERR_BAD_PARAMETER);
1928 }
1929
1930 return (KMF_OK);
1931 }
1932
1933 KMF_RETURN
kmf_set_cert_validity(KMF_X509_CERTIFICATE * CertData,time_t notBefore,uint32_t delta)1934 kmf_set_cert_validity(KMF_X509_CERTIFICATE *CertData,
1935 time_t notBefore, uint32_t delta)
1936 {
1937 time_t clock;
1938 struct tm *gmt;
1939 char szNotBefore[256];
1940 char szNotAfter[256];
1941
1942 if (CertData == NULL)
1943 return (KMF_ERR_BAD_PARAMETER);
1944
1945 /* Set up validity fields */
1946 if (notBefore == 0)
1947 clock = time(NULL);
1948 else
1949 clock = notBefore;
1950
1951 gmt = gmtime(&clock); /* valid starting today */
1952
1953 /* Build the format in 2 parts so SCCS doesn't get confused */
1954 (void) strftime(szNotBefore, sizeof (szNotBefore),
1955 "%y%m%d%H" "%M00Z", gmt);
1956
1957 CertData->certificate.validity.notBefore.timeType = BER_UTCTIME;
1958 CertData->certificate.validity.notBefore.time.Length =
1959 strlen((char *)szNotBefore);
1960 CertData->certificate.validity.notBefore.time.Data =
1961 (uchar_t *)strdup(szNotBefore);
1962
1963 clock += delta;
1964 gmt = gmtime(&clock);
1965
1966 /* Build the format in 2 parts so SCCS doesn't get confused */
1967 (void) strftime(szNotAfter, sizeof (szNotAfter),
1968 "%y%m%d%H" "%M00Z", gmt);
1969
1970 CertData->certificate.validity.notAfter.timeType = BER_UTCTIME;
1971 CertData->certificate.validity.notAfter.time.Length =
1972 strlen((char *)szNotAfter);
1973 CertData->certificate.validity.notAfter.time.Data =
1974 (uchar_t *)strdup(szNotAfter);
1975
1976 return (KMF_OK);
1977 }
1978
1979 /*
1980 * Utility routine to set Integer values in the Certificate template
1981 * for things like serialNumber and Version. The data structure
1982 * expects pointers, not literal values, so we must allocate
1983 * and copy here. Don't use memory from the stack since this data
1984 * is freed later and that would be bad.
1985 */
1986 KMF_RETURN
set_integer(KMF_DATA * data,void * value,int length)1987 set_integer(KMF_DATA *data, void *value, int length)
1988 {
1989 if (data == NULL || value == NULL)
1990 return (KMF_ERR_BAD_PARAMETER);
1991
1992 data->Data = malloc(length);
1993 if (data->Data == NULL)
1994 return (KMF_ERR_MEMORY);
1995
1996 data->Length = length;
1997 (void) memcpy((void *)data->Data, (const void *)value, length);
1998
1999 return (KMF_OK);
2000 }
2001
2002 static KMF_RETURN
set_bigint(KMF_BIGINT * data,KMF_BIGINT * bigint)2003 set_bigint(KMF_BIGINT *data, KMF_BIGINT *bigint)
2004 {
2005 if (data == NULL || bigint == NULL || bigint->len == 0)
2006 return (KMF_ERR_BAD_PARAMETER);
2007
2008 data->val = malloc(bigint->len);
2009 if (data->val == NULL)
2010 return (KMF_ERR_MEMORY);
2011
2012 data->len = bigint->len;
2013
2014 (void) memcpy((void *)data->val, bigint->val, bigint->len);
2015
2016 return (KMF_OK);
2017
2018 }
2019
2020 KMF_RETURN
kmf_set_cert_serial(KMF_X509_CERTIFICATE * CertData,KMF_BIGINT * serno)2021 kmf_set_cert_serial(KMF_X509_CERTIFICATE *CertData,
2022 KMF_BIGINT *serno)
2023 {
2024 if (CertData == NULL || serno == NULL || serno->len == 0)
2025 return (KMF_ERR_BAD_PARAMETER);
2026 return (set_bigint(&CertData->certificate.serialNumber, serno));
2027 }
2028
2029 KMF_RETURN
kmf_set_cert_version(KMF_X509_CERTIFICATE * CertData,uint32_t version)2030 kmf_set_cert_version(KMF_X509_CERTIFICATE *CertData,
2031 uint32_t version)
2032 {
2033 if (CertData == NULL)
2034 return (KMF_ERR_BAD_PARAMETER);
2035 /*
2036 * From RFC 3280:
2037 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
2038 */
2039 if (version != 0 && version != 1 && version != 2)
2040 return (KMF_ERR_BAD_PARAMETER);
2041 return (set_integer(&CertData->certificate.version, (void *)&version,
2042 sizeof (uint32_t)));
2043 }
2044
2045 KMF_RETURN
kmf_set_cert_issuer_altname(KMF_X509_CERTIFICATE * CertData,int critical,KMF_GENERALNAMECHOICES nametype,char * namedata)2046 kmf_set_cert_issuer_altname(KMF_X509_CERTIFICATE *CertData,
2047 int critical,
2048 KMF_GENERALNAMECHOICES nametype,
2049 char *namedata)
2050 {
2051 if (CertData == NULL || namedata == NULL)
2052 return (KMF_ERR_BAD_PARAMETER);
2053
2054 return (kmf_set_altname(&CertData->certificate.extensions,
2055 (KMF_OID *)&KMFOID_IssuerAltName, critical, nametype, namedata));
2056 }
2057
2058 KMF_RETURN
kmf_set_cert_subject_altname(KMF_X509_CERTIFICATE * CertData,int critical,KMF_GENERALNAMECHOICES nametype,char * namedata)2059 kmf_set_cert_subject_altname(KMF_X509_CERTIFICATE *CertData,
2060 int critical,
2061 KMF_GENERALNAMECHOICES nametype,
2062 char *namedata)
2063 {
2064 if (CertData == NULL || namedata == NULL)
2065 return (KMF_ERR_BAD_PARAMETER);
2066
2067 return (kmf_set_altname(&CertData->certificate.extensions,
2068 (KMF_OID *)&KMFOID_SubjectAltName, critical, nametype, namedata));
2069 }
2070
2071 KMF_RETURN
kmf_add_cert_eku(KMF_X509_CERTIFICATE * CertData,KMF_OID * ekuOID,int critical)2072 kmf_add_cert_eku(KMF_X509_CERTIFICATE *CertData, KMF_OID *ekuOID,
2073 int critical)
2074 {
2075 KMF_RETURN ret = KMF_OK;
2076 KMF_X509_EXTENSION *foundextn;
2077 KMF_X509_EXTENSION newextn;
2078 BerElement *asn1 = NULL;
2079 BerValue *extdata = NULL;
2080 char *olddata = NULL;
2081 size_t oldsize = 0;
2082 KMF_X509EXT_EKU ekudata;
2083
2084 if (CertData == NULL || ekuOID == NULL)
2085 return (KMF_ERR_BAD_PARAMETER);
2086
2087 (void) memset(&ekudata, 0, sizeof (KMF_X509EXT_EKU));
2088 (void) memset(&newextn, 0, sizeof (newextn));
2089
2090 foundextn = FindExtn(&CertData->certificate.extensions,
2091 (KMF_OID *)&KMFOID_ExtendedKeyUsage);
2092 if (foundextn != NULL) {
2093 ret = GetSequenceContents((char *)foundextn->BERvalue.Data,
2094 foundextn->BERvalue.Length, &olddata, &oldsize);
2095 if (ret != KMF_OK)
2096 goto out;
2097
2098 /*
2099 * If the EKU is already in the cert, then just return OK.
2100 */
2101 ret = parse_eku_data(&foundextn->BERvalue, &ekudata);
2102 if (ret == KMF_OK) {
2103 if (is_eku_present(&ekudata, ekuOID)) {
2104 goto out;
2105 }
2106 }
2107 }
2108 if ((asn1 = kmfder_alloc()) == NULL)
2109 return (KMF_ERR_MEMORY);
2110
2111 if (kmfber_printf(asn1, "{") == -1) {
2112 ret = KMF_ERR_ENCODING;
2113 goto out;
2114 }
2115
2116 /* Write the old extension data first */
2117 if (olddata != NULL && oldsize > 0) {
2118 if (kmfber_write(asn1, olddata, oldsize, 0) == -1) {
2119 ret = KMF_ERR_ENCODING;
2120 goto out;
2121 }
2122 }
2123
2124 /* Append this EKU OID and close the sequence */
2125 if (kmfber_printf(asn1, "D}", ekuOID) == -1) {
2126 ret = KMF_ERR_ENCODING;
2127 goto out;
2128 }
2129
2130 if (kmfber_flatten(asn1, &extdata) == -1) {
2131 ret = KMF_ERR_ENCODING;
2132 goto out;
2133 }
2134
2135 /*
2136 * If we are just adding to an existing list of EKU OIDs,
2137 * just replace the BER data associated with the found extension.
2138 */
2139 if (foundextn != NULL) {
2140 free(foundextn->BERvalue.Data);
2141 foundextn->critical = critical;
2142 foundextn->BERvalue.Data = (uchar_t *)extdata->bv_val;
2143 foundextn->BERvalue.Length = extdata->bv_len;
2144 } else {
2145 ret = copy_data(&newextn.extnId,
2146 (KMF_DATA *)&KMFOID_ExtendedKeyUsage);
2147 if (ret != KMF_OK)
2148 goto out;
2149 newextn.critical = critical;
2150 newextn.format = KMF_X509_DATAFORMAT_ENCODED;
2151 newextn.BERvalue.Data = (uchar_t *)extdata->bv_val;
2152 newextn.BERvalue.Length = extdata->bv_len;
2153 ret = kmf_set_cert_extn(CertData, &newextn);
2154 if (ret != KMF_OK)
2155 free(newextn.BERvalue.Data);
2156 }
2157
2158 out:
2159 kmf_free_eku(&ekudata);
2160 if (extdata != NULL)
2161 free(extdata);
2162
2163 if (olddata != NULL)
2164 free(olddata);
2165
2166 if (asn1 != NULL)
2167 kmfber_free(asn1, 1);
2168
2169 if (ret != KMF_OK)
2170 kmf_free_data(&newextn.extnId);
2171
2172 return (ret);
2173 }
2174
2175 KMF_RETURN
kmf_set_cert_extn(KMF_X509_CERTIFICATE * CertData,KMF_X509_EXTENSION * extn)2176 kmf_set_cert_extn(KMF_X509_CERTIFICATE *CertData,
2177 KMF_X509_EXTENSION *extn)
2178 {
2179 KMF_RETURN ret = KMF_OK;
2180 KMF_X509_EXTENSIONS *exts;
2181
2182 if (CertData == NULL || extn == NULL)
2183 return (KMF_ERR_BAD_PARAMETER);
2184
2185 exts = &CertData->certificate.extensions;
2186
2187 ret = add_an_extension(exts, extn);
2188
2189 return (ret);
2190 }
2191
2192 KMF_RETURN
kmf_set_cert_basic_constraint(KMF_X509_CERTIFICATE * CertData,KMF_BOOL critical,KMF_X509EXT_BASICCONSTRAINTS * constraint)2193 kmf_set_cert_basic_constraint(KMF_X509_CERTIFICATE *CertData,
2194 KMF_BOOL critical, KMF_X509EXT_BASICCONSTRAINTS *constraint)
2195 {
2196 KMF_RETURN ret = KMF_OK;
2197 KMF_X509_EXTENSION extn;
2198 BerElement *asn1 = NULL;
2199 BerValue *extdata;
2200
2201 if ((CertData == NULL) || (constraint == NULL))
2202 return (KMF_ERR_BAD_PARAMETER);
2203
2204 (void) memset(&extn, 0, sizeof (extn));
2205 ret = copy_data(&extn.extnId, (KMF_OID *)&KMFOID_BasicConstraints);
2206 if (ret != KMF_OK)
2207 return (ret);
2208 extn.critical = critical;
2209 extn.format = KMF_X509_DATAFORMAT_ENCODED;
2210
2211 if ((asn1 = kmfder_alloc()) == NULL)
2212 return (KMF_ERR_MEMORY);
2213
2214 if (kmfber_printf(asn1, "{") == -1) {
2215 ret = KMF_ERR_ENCODING;
2216 goto out;
2217 }
2218
2219 if (kmfber_printf(asn1, "b", constraint->cA) == -1) {
2220 ret = KMF_ERR_ENCODING;
2221 goto out;
2222 }
2223
2224 if (constraint->pathLenConstraintPresent) {
2225 /* Write the pathLenConstraint value */
2226 if (kmfber_printf(asn1, "i",
2227 constraint->pathLenConstraint) == -1) {
2228 ret = KMF_ERR_ENCODING;
2229 goto out;
2230 }
2231 }
2232
2233 if (kmfber_printf(asn1, "}") == -1) {
2234 ret = KMF_ERR_ENCODING;
2235 goto out;
2236 }
2237
2238 if (kmfber_flatten(asn1, &extdata) == -1) {
2239 ret = KMF_ERR_ENCODING;
2240 goto out;
2241 }
2242
2243 extn.BERvalue.Data = (uchar_t *)extdata->bv_val;
2244 extn.BERvalue.Length = extdata->bv_len;
2245
2246 free(extdata);
2247 ret = kmf_set_cert_extn(CertData, &extn);
2248 if (ret != KMF_OK) {
2249 free(extn.BERvalue.Data);
2250 }
2251
2252 out:
2253 if (asn1 != NULL)
2254 kmfber_free(asn1, 1);
2255
2256 return (ret);
2257 }
2258
2259
2260 /*
2261 * Phase 1 APIs still needed to maintain compat with elfsign.
2262 */
2263 KMF_RETURN
KMF_GetCertSubjectNameString(KMF_HANDLE_T handle,const KMF_DATA * SignedCert,char ** result)2264 KMF_GetCertSubjectNameString(KMF_HANDLE_T handle, const KMF_DATA *SignedCert,
2265 char **result)
2266 {
2267 return (kmf_get_cert_subject_str(handle, SignedCert, result));
2268 }
2269
2270 KMF_RETURN
KMF_GetCertIssuerNameString(KMF_HANDLE_T handle,const KMF_DATA * SignedCert,char ** result)2271 KMF_GetCertIssuerNameString(KMF_HANDLE_T handle, const KMF_DATA *SignedCert,
2272 char **result)
2273 {
2274 return (kmf_get_cert_issuer_str(handle, SignedCert, result));
2275 }
2276
2277 KMF_RETURN
KMF_GetCertIDString(const KMF_DATA * SignedCert,char ** idstr)2278 KMF_GetCertIDString(const KMF_DATA *SignedCert, char **idstr)
2279 {
2280 return (kmf_get_cert_id_str(SignedCert, idstr));
2281 }
2282