1 /*
2 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
4 */
5 /*
6 * Copyright (c) 1995-1999 Intel Corporation. All rights reserved.
7 */
8
9 #include <strings.h>
10 #include <kmftypes.h>
11 #include <ber_der.h>
12 #include <kmfber_int.h>
13 #include <kmfapi.h>
14 #include <kmfapiP.h>
15
16 #include <stdio.h>
17
18 #define DSA_RAW_SIG_LEN 40
19
20 static uint8_t OID_ExtensionRequest[] = { OID_PKCS_9, 14 };
21 const KMF_OID extension_request_oid = {OID_PKCS_9_LENGTH + 1,
22 OID_ExtensionRequest};
23
24 static KMF_RETURN
encode_algoid(BerElement * asn1,KMF_X509_ALGORITHM_IDENTIFIER * algoid,boolean_t encode_params)25 encode_algoid(BerElement *asn1, KMF_X509_ALGORITHM_IDENTIFIER *algoid,
26 boolean_t encode_params)
27 {
28 KMF_RETURN ret = KMF_OK;
29
30 if (kmfber_printf(asn1, "{D", &algoid->algorithm) == -1) {
31 ret = KMF_ERR_BAD_CERT_FORMAT;
32 }
33 if (!encode_params) {
34 if (kmfber_printf(asn1, "}") == -1)
35 return (KMF_ERR_BAD_CERT_FORMAT);
36 } else if (algoid->parameters.Data == NULL ||
37 algoid->parameters.Length == 0) {
38 if (kmfber_printf(asn1, "n}") == -1)
39 return (KMF_ERR_BAD_CERT_FORMAT);
40 } else {
41 /*
42 * The algorithm data can be anything, so we just write it
43 * straight into the buffer. It is already DER encoded.
44 */
45 (void) kmfber_write(asn1, (char *)algoid->parameters.Data,
46 algoid->parameters.Length, 0);
47 if (kmfber_printf(asn1, "}") == -1) {
48 ret = KMF_ERR_BAD_CERT_FORMAT;
49 }
50 }
51
52 return (ret);
53 }
54
55 static void
free_data(KMF_DATA * data)56 free_data(KMF_DATA *data)
57 {
58 if (data == NULL || data->Data == NULL)
59 return;
60
61 free(data->Data);
62 data->Data = NULL;
63 data->Length = 0;
64 }
65
66 static void
free_algoid(KMF_X509_ALGORITHM_IDENTIFIER * algoid)67 free_algoid(KMF_X509_ALGORITHM_IDENTIFIER *algoid)
68 {
69 free_data(&algoid->algorithm);
70 free_data(&algoid->parameters);
71 }
72
73 static void
free_decoded_spki(KMF_X509_SPKI * spki)74 free_decoded_spki(KMF_X509_SPKI *spki)
75 {
76 if (spki != NULL) {
77 free_algoid(&spki->algorithm);
78 free_data(&spki->subjectPublicKey);
79 }
80 }
81
82 static void
free_rdn_data(KMF_X509_NAME * name)83 free_rdn_data(KMF_X509_NAME *name)
84 {
85 KMF_X509_RDN *newrdn = NULL;
86 KMF_X509_TYPE_VALUE_PAIR *av = NULL;
87 int i, j;
88
89 if (name && name->numberOfRDNs) {
90 for (i = 0; i < name->numberOfRDNs; i++) {
91 newrdn = &name->RelativeDistinguishedName[i];
92 for (j = 0; j < newrdn->numberOfPairs; j++) {
93 av = &newrdn->AttributeTypeAndValue[j];
94 free_data(&av->type);
95 free_data(&av->value);
96 }
97 free(newrdn->AttributeTypeAndValue);
98 }
99 free(name->RelativeDistinguishedName);
100 name->numberOfRDNs = 0;
101 name->RelativeDistinguishedName = NULL;
102 }
103 }
104
105 static void
free_validity(KMF_X509_VALIDITY * validity)106 free_validity(KMF_X509_VALIDITY *validity)
107 {
108 free_data(&validity->notBefore.time);
109 free_data(&validity->notAfter.time);
110 }
111
112 static void
free_one_extension(KMF_X509_EXTENSION * exptr)113 free_one_extension(KMF_X509_EXTENSION *exptr)
114 {
115 free_data(&exptr->extnId);
116 free_data(&exptr->BERvalue);
117
118 if (exptr->value.tagAndValue) {
119 free_data(&exptr->value.tagAndValue->value);
120 free(exptr->value.tagAndValue);
121 }
122 }
123
124 static void
free_extensions(KMF_X509_EXTENSIONS * extns)125 free_extensions(KMF_X509_EXTENSIONS *extns)
126 {
127 int i;
128 KMF_X509_EXTENSION *exptr;
129
130 if (extns && extns->numberOfExtensions > 0) {
131 for (i = 0; i < extns->numberOfExtensions; i++) {
132 exptr = &extns->extensions[i];
133 free_one_extension(exptr);
134 }
135 free(extns->extensions);
136 extns->numberOfExtensions = 0;
137 extns->extensions = NULL;
138 }
139 }
140
141 static void
free_tbscsr(KMF_TBS_CSR * tbscsr)142 free_tbscsr(KMF_TBS_CSR *tbscsr)
143 {
144 if (tbscsr) {
145 free_data(&tbscsr->version);
146
147 free_rdn_data(&tbscsr->subject);
148
149 free_decoded_spki(&tbscsr->subjectPublicKeyInfo);
150
151 free_extensions(&tbscsr->extensions);
152 }
153 }
154
155
156 static void
free_bigint(KMF_BIGINT * bn)157 free_bigint(KMF_BIGINT *bn)
158 {
159 if (bn != NULL && bn->val != NULL) {
160 free(bn->val);
161 bn->val = NULL;
162 bn->len = 0;
163 }
164 }
165
166 static void
free_tbscert(KMF_X509_TBS_CERT * tbscert)167 free_tbscert(KMF_X509_TBS_CERT *tbscert)
168 {
169 if (tbscert) {
170 free_data(&tbscert->version);
171 free_bigint(&tbscert->serialNumber);
172 free_algoid(&tbscert->signature);
173
174 free_rdn_data(&tbscert->issuer);
175 free_rdn_data(&tbscert->subject);
176
177 free_validity(&tbscert->validity);
178
179 free_data(&tbscert->issuerUniqueIdentifier);
180 free_data(&tbscert->subjectUniqueIdentifier);
181 free_decoded_spki(&tbscert->subjectPublicKeyInfo);
182 free_extensions(&tbscert->extensions);
183
184 free_data(&tbscert->issuerUniqueIdentifier);
185 free_data(&tbscert->subjectUniqueIdentifier);
186 }
187 }
188
189 static void
free_decoded_cert(KMF_X509_CERTIFICATE * certptr)190 free_decoded_cert(KMF_X509_CERTIFICATE *certptr)
191 {
192 if (!certptr)
193 return;
194
195 free_tbscert(&certptr->certificate);
196
197 free_algoid(&certptr->signature.algorithmIdentifier);
198 free_data(&certptr->signature.encrypted);
199 }
200
201 static KMF_RETURN
get_sequence_data(BerElement * asn1,BerValue * seqdata)202 get_sequence_data(BerElement *asn1, BerValue *seqdata)
203 {
204 ber_tag_t tag;
205 ber_len_t size;
206
207 tag = kmfber_next_element(asn1, &size, NULL);
208 if (tag == BER_OBJECT_IDENTIFIER) {
209 /* The whole block is the OID. */
210 size += kmfber_calc_taglen(tag) + kmfber_calc_lenlen(size);
211 seqdata->bv_val = malloc(size);
212 if (seqdata->bv_val == NULL) {
213 return (KMF_ERR_MEMORY);
214 }
215 /* read the raw data into the Algoritm params area. */
216 if (kmfber_read(asn1, seqdata->bv_val, size) ==
217 -1) {
218 return (KMF_ERR_BAD_CERT_FORMAT);
219 }
220 seqdata->bv_len = size;
221 return (KMF_OK);
222 } else if (tag != BER_CONSTRUCTED_SEQUENCE)
223 return (KMF_ERR_BAD_CERT_FORMAT);
224
225 if ((kmfber_scanf(asn1, "tl", &tag, &size)) == -1) {
226 return (KMF_ERR_BAD_CERT_FORMAT);
227 }
228 /*
229 * We need to read the tag and the length bytes too,
230 * so adjust the size.
231 */
232 size += kmfber_calc_taglen(tag) + kmfber_calc_lenlen(size);
233 seqdata->bv_val = malloc(size);
234 if (seqdata->bv_val == NULL) {
235 return (KMF_ERR_MEMORY);
236 }
237 /* read the raw data into the Algoritm params area. */
238 if (kmfber_read(asn1, seqdata->bv_val, size) ==
239 -1) {
240 return (KMF_ERR_BAD_CERT_FORMAT);
241 }
242 seqdata->bv_len = size;
243 return (KMF_OK);
244 }
245
246 static KMF_RETURN
get_algoid(BerElement * asn1,KMF_X509_ALGORITHM_IDENTIFIER * algoid)247 get_algoid(BerElement *asn1, KMF_X509_ALGORITHM_IDENTIFIER *algoid)
248 {
249 KMF_RETURN rv = KMF_OK;
250 ber_tag_t tag;
251 ber_len_t size;
252 BerValue algoid_data;
253 BerValue AlgOID;
254 BerElement *oidasn1 = NULL;
255
256 /* Read the entire OID seq into it's own data block */
257 rv = get_sequence_data(asn1, &algoid_data);
258 if (rv != KMF_OK)
259 return (rv);
260
261 /* Now parse just this block so we don't overrun */
262 if ((oidasn1 = kmfder_init(&algoid_data)) == NULL)
263 return (KMF_ERR_MEMORY);
264 tag = kmfber_next_element(oidasn1, &size, NULL);
265 if (tag == BER_OBJECT_IDENTIFIER) {
266 algoid->algorithm.Data = (uchar_t *)algoid_data.bv_val;
267 algoid->algorithm.Length = algoid_data.bv_len;
268 algoid->parameters.Data = NULL;
269 algoid->parameters.Length = 0;
270 kmfber_free(oidasn1, 1);
271 return (KMF_OK);
272 }
273
274 if ((tag = kmfber_scanf(oidasn1, "{D", &AlgOID)) == -1) {
275 kmfber_free(oidasn1, 1);
276 return (KMF_ERR_BAD_CERT_FORMAT);
277 }
278 algoid->algorithm.Data = (uchar_t *)AlgOID.bv_val;
279 algoid->algorithm.Length = AlgOID.bv_len;
280
281 tag = kmfber_next_element(oidasn1, &size, NULL);
282 if (tag == BER_NULL) {
283 (void) kmfber_scanf(oidasn1, "n}");
284 algoid->parameters.Data = NULL;
285 algoid->parameters.Length = 0;
286 } else if (tag == KMFBER_END_OF_SEQORSET || tag == KMFBER_DEFAULT) {
287 /* close sequence, we are done with Algoid */
288 algoid->parameters.Data = NULL;
289 algoid->parameters.Length = 0;
290 } else {
291 /* The rest of the data is the algorithm parameters */
292 if ((kmfber_scanf(oidasn1, "tl", &tag, &size)) == -1) {
293 rv = KMF_ERR_BAD_CERT_FORMAT;
294 goto cleanup;
295 }
296
297 /*
298 * We need to read the tag and the length bytes too,
299 * so adjust the size.
300 */
301 size += kmfber_calc_taglen(tag) + kmfber_calc_lenlen(size);
302 algoid->parameters.Data = malloc(size);
303 if (algoid->parameters.Data == NULL) {
304 rv = KMF_ERR_MEMORY;
305 goto cleanup;
306 }
307 /* read the raw data into the Algoritm params area. */
308 if (kmfber_read(oidasn1, (char *)algoid->parameters.Data,
309 size) == -1) {
310 rv = KMF_ERR_BAD_CERT_FORMAT;
311 goto cleanup;
312 }
313 algoid->parameters.Length = size;
314 }
315 cleanup:
316 if (rv != KMF_OK) {
317 free_algoid(algoid);
318 }
319 kmfber_free(oidasn1, 1);
320
321 return (rv);
322 }
323
324 static KMF_RETURN
CopyData(KMF_DATA * src,KMF_DATA * dst)325 CopyData(KMF_DATA *src, KMF_DATA *dst)
326 {
327 if (src && dst && src->Data != NULL && src->Length > 0) {
328 dst->Length = src->Length;
329 dst->Data = malloc(dst->Length);
330 if (dst->Data == NULL)
331 return (KMF_ERR_MEMORY);
332 (void) memcpy(dst->Data, src->Data, src->Length);
333 }
334 return (KMF_OK);
335 }
336
337 static KMF_RETURN
encode_spki(BerElement * asn1,KMF_X509_SPKI * spki)338 encode_spki(BerElement *asn1, KMF_X509_SPKI *spki)
339 {
340 KMF_RETURN ret = KMF_OK;
341
342 if (kmfber_printf(asn1, "{") == -1)
343 return (KMF_ERR_BAD_CERT_FORMAT);
344
345 /*
346 * The SPKI is the only place where algorithm parameters
347 * should be encoded.
348 */
349 if ((ret = encode_algoid(asn1, &spki->algorithm, TRUE)) != KMF_OK)
350 return (ret);
351
352 if (kmfber_printf(asn1, "B}", spki->subjectPublicKey.Data,
353 spki->subjectPublicKey.Length * 8) == -1)
354 return (KMF_ERR_BAD_CERT_FORMAT);
355
356 return (ret);
357 }
358
359 KMF_RETURN
DerEncodeSPKI(KMF_X509_SPKI * spki,KMF_DATA * EncodedSPKI)360 DerEncodeSPKI(KMF_X509_SPKI *spki, KMF_DATA *EncodedSPKI)
361 {
362 KMF_RETURN ret = KMF_OK;
363 BerElement *asn1;
364 BerValue *result;
365
366 if (spki == NULL || EncodedSPKI == NULL)
367 return (KMF_ERR_BAD_PARAMETER);
368
369 if ((asn1 = kmfder_alloc()) == NULL)
370 return (KMF_ERR_MEMORY);
371
372 if ((ret = encode_spki(asn1, spki)) != KMF_OK) {
373 return (ret);
374 }
375
376 if (kmfber_flatten(asn1, &result) == -1) {
377 kmfber_free(asn1, 1);
378 return (KMF_ERR_ENCODING);
379 }
380
381 EncodedSPKI->Data = (uchar_t *)result->bv_val;
382 EncodedSPKI->Length = result->bv_len;
383
384 free(result);
385 kmfber_free(asn1, 1);
386 return (KMF_OK);
387 }
388
389 static KMF_RETURN
get_spki(BerElement * asn1,KMF_X509_SPKI * spki)390 get_spki(BerElement *asn1, KMF_X509_SPKI *spki)
391 {
392 KMF_RETURN ret = KMF_OK;
393 char *bitstr = NULL;
394 ber_len_t size;
395
396 if (kmfber_scanf(asn1, "{") == -1)
397 return (KMF_ERR_BAD_CERT_FORMAT);
398
399 if ((ret = get_algoid(asn1, &spki->algorithm)) != KMF_OK)
400 return (ret);
401
402 if (kmfber_scanf(asn1, "B}", &bitstr, &size) == BER_BIT_STRING) {
403 spki->subjectPublicKey.Data = (uchar_t *)bitstr;
404 spki->subjectPublicKey.Length = size / 8;
405 } else {
406 ret = KMF_ERR_BAD_CERT_FORMAT;
407 goto cleanup;
408 }
409 cleanup:
410 if (ret != KMF_OK) {
411 if (bitstr != NULL)
412 free(bitstr);
413 spki->subjectPublicKey.Data = NULL;
414 spki->subjectPublicKey.Length = 0;
415
416 free_algoid(&spki->algorithm);
417 }
418 return (ret);
419 }
420
421
422 KMF_RETURN
DerEncodeDSASignature(KMF_DATA * rawdata,KMF_DATA * signature)423 DerEncodeDSASignature(KMF_DATA *rawdata, KMF_DATA *signature)
424 {
425 BerElement *asn1;
426 BerValue *buf;
427 int n;
428
429 if (rawdata == NULL || signature == NULL)
430 return (KMF_ERR_BAD_PARAMETER);
431
432 if (rawdata->Data == NULL || rawdata->Length == 0)
433 return (KMF_ERR_BAD_PARAMETER);
434
435 asn1 = kmfder_alloc();
436 if (asn1 == NULL)
437 return (KMF_ERR_MEMORY);
438
439 /*
440 * The [EC]DSA signature is the concatenation of 2
441 * bignum values.
442 */
443 n = rawdata->Length/2;
444 if (kmfber_printf(asn1, "{II}",
445 rawdata->Data, n, &rawdata->Data[n], n) == -1) {
446 kmfber_free(asn1, 1);
447 return (KMF_ERR_MEMORY);
448 }
449
450 if (kmfber_flatten(asn1, &buf) == -1) {
451 kmfber_free(asn1, 1);
452 return (KMF_ERR_ENCODING);
453 }
454
455 signature->Data = (uchar_t *)buf->bv_val;
456 signature->Length = buf->bv_len;
457
458 kmfber_free(asn1, 1);
459 free(buf);
460
461 return (KMF_OK);
462 }
463
464 /*
465 * ECDSA and DSA encode signatures the same way.
466 */
467 KMF_RETURN
DerEncodeECDSASignature(KMF_DATA * rawdata,KMF_DATA * signature)468 DerEncodeECDSASignature(KMF_DATA *rawdata, KMF_DATA *signature)
469 {
470 return (DerEncodeDSASignature(rawdata, signature));
471 }
472
473 /*
474 * Convert a signed DSA sig to a fixed-length unsigned one.
475 * This is necessary because DER encoding seeks to use the
476 * minimal amount of bytes but we need a full 20 byte DSA
477 * value with leading 0x00 bytes.
478 */
479 static KMF_RETURN
convert_signed_to_fixed(BerValue * src,BerValue * dst)480 convert_signed_to_fixed(BerValue *src, BerValue *dst)
481 {
482 int cnt;
483 char *p;
484 if (dst->bv_len > src->bv_len) {
485 cnt = dst->bv_len - src->bv_len;
486 /* prepend with leading 0s */
487 (void) memset(dst->bv_val, 0x00, cnt);
488 (void) memcpy(dst->bv_val + cnt, src->bv_val,
489 src->bv_len);
490 return (KMF_OK);
491 }
492 if (dst->bv_len == src->bv_len) {
493 (void) memcpy(dst->bv_val, src->bv_val,
494 dst->bv_len);
495 return (KMF_OK);
496 }
497 /*
498 * src is larger than dest, strip leading 0s.
499 * This should not be necessary, but do it just in case.
500 */
501 cnt = src->bv_len - dst->bv_len;
502 p = src->bv_val;
503 while (cnt-- > 0) {
504 if (*p++ != 0x00)
505 return (KMF_ERR_ENCODING);
506 }
507 (void) memcpy(dst->bv_val, p, dst->bv_len);
508 return (KMF_OK);
509 }
510
511 KMF_RETURN
DerDecodeDSASignature(KMF_DATA * encoded,KMF_DATA * signature)512 DerDecodeDSASignature(KMF_DATA *encoded, KMF_DATA *signature)
513 {
514 KMF_RETURN ret = KMF_OK;
515 BerElement *asn1 = NULL;
516 BerValue buf, *R = NULL, *S = NULL;
517 BerValue fixedR, fixedS;
518
519 buf.bv_val = (char *)encoded->Data;
520 buf.bv_len = encoded->Length;
521
522 if (encoded == NULL || encoded->Data == NULL ||
523 signature == NULL)
524 return (KMF_ERR_BAD_PARAMETER);
525
526 signature->Data = NULL;
527 signature->Length = 0;
528
529 if ((asn1 = kmfder_init(&buf)) == NULL)
530 return (KMF_ERR_MEMORY);
531
532 if (kmfber_scanf(asn1, "{II}", &R, &S) == -1) {
533 ret = KMF_ERR_BAD_PARAMETER;
534 goto cleanup;
535 }
536 signature->Length = R->bv_len + S->bv_len;
537 /*
538 * If either of the values had a leading 0 lopped off
539 * they will be 1 byte short and need to be adjusted below.
540 * The stripping is correct as per ASN.1 rules.
541 *
542 * We don't know the exact length that the R and S values
543 * must be, it depends on the signature algorithm and,
544 * in the case of EC, the curve used. So instead of
545 * checking for a specific length, we just check to see
546 * if the value came out to be an odd number. If so,
547 * then we know it needs a leading 0x00 byte which
548 * will be added below when we convert it to a fixed
549 * length.
550 */
551 if ((R->bv_len % 2) != 0)
552 signature->Length++;
553 if ((S->bv_len % 2) != 0)
554 signature->Length++;
555
556 signature->Data = malloc(signature->Length);
557 if (signature->Data == NULL) {
558 ret = KMF_ERR_MEMORY;
559 goto cleanup;
560 }
561 fixedR.bv_val = (char *)signature->Data;
562 /* adjust length if it needs a leading 0x00 byte */
563 fixedR.bv_len = R->bv_len + (R->bv_len % 2);
564
565 fixedS.bv_val = (char *)(signature->Data + fixedR.bv_len);
566 /* adjust length if it needs a leading 0x00 byte */
567 fixedS.bv_len = S->bv_len + (S->bv_len % 2);
568
569 /*
570 * This will add back any missing leading 0's
571 * that were stripped off earlier when the signature
572 * was parsed. This ensures that the 2 parts of the
573 * signature are the right length and have the proper
574 * leading 0's prepended.
575 */
576 ret = convert_signed_to_fixed(R, &fixedR);
577 if (ret)
578 goto cleanup;
579
580 ret = convert_signed_to_fixed(S, &fixedS);
581 cleanup:
582 if (R && R->bv_val)
583 free(R->bv_val);
584 if (S && S->bv_val)
585 free(S->bv_val);
586
587 if (S) free(S);
588 if (R) free(R);
589
590 if (asn1) kmfber_free(asn1, 1);
591
592 return (ret);
593 }
594
595 KMF_RETURN
DerDecodeECDSASignature(KMF_DATA * encoded,KMF_DATA * signature)596 DerDecodeECDSASignature(KMF_DATA *encoded, KMF_DATA *signature)
597 {
598 /* ECDSA can be decoded using same code as standard DSA */
599 return (DerDecodeDSASignature(encoded, signature));
600 }
601
602 KMF_RETURN
DerDecodeSPKI(KMF_DATA * EncodedSPKI,KMF_X509_SPKI * spki)603 DerDecodeSPKI(KMF_DATA *EncodedSPKI, KMF_X509_SPKI *spki)
604 {
605 KMF_RETURN ret = KMF_OK;
606 BerElement *asn1;
607 BerValue bv;
608
609 if (EncodedSPKI == NULL || EncodedSPKI->Data == NULL ||
610 spki == NULL)
611 return (KMF_ERR_BAD_PARAMETER);
612
613 (void) memset(spki, 0, sizeof (KMF_X509_SPKI));
614
615 bv.bv_val = (char *)EncodedSPKI->Data;
616 bv.bv_len = EncodedSPKI->Length;
617
618 if ((asn1 = kmfder_init(&bv)) == NULL)
619 return (KMF_ERR_MEMORY);
620
621 ret = get_spki(asn1, spki);
622
623 if (ret != KMF_OK) {
624 free_decoded_spki(spki);
625 }
626 kmfber_free(asn1, 1);
627
628 return (ret);
629 }
630
631 KMF_RETURN
CopySPKI(KMF_X509_SPKI * src,KMF_X509_SPKI ** dest)632 CopySPKI(KMF_X509_SPKI *src,
633 KMF_X509_SPKI **dest)
634 {
635 KMF_RETURN ret = KMF_OK;
636 KMF_X509_SPKI *newspki;
637
638 *dest = NULL;
639
640 newspki = malloc(sizeof (KMF_X509_SPKI));
641 if (newspki == NULL)
642 return (KMF_ERR_MEMORY);
643 (void) memset(newspki, 0, sizeof (KMF_X509_SPKI));
644
645 ret = CopyData(&src->algorithm.algorithm,
646 &newspki->algorithm.algorithm);
647 if (ret != KMF_OK)
648 goto cleanup;
649
650 ret = CopyData(&src->algorithm.parameters,
651 &newspki->algorithm.parameters);
652 if (ret != KMF_OK)
653 goto cleanup;
654
655 ret = CopyData(&src->subjectPublicKey,
656 &newspki->subjectPublicKey);
657 if (ret != KMF_OK)
658 goto cleanup;
659
660 *dest = newspki;
661 cleanup:
662 if (ret != KMF_OK) {
663 if (newspki)
664 free_decoded_spki(newspki);
665 }
666 return (ret);
667 }
668
669 static KMF_RETURN
encode_validity(BerElement * asn1,KMF_X509_VALIDITY * validity)670 encode_validity(BerElement *asn1, KMF_X509_VALIDITY *validity)
671 {
672 int ret;
673
674 ret = kmfber_printf(asn1, "{tsts}",
675 validity->notBefore.timeType,
676 validity->notBefore.time.Data,
677 validity->notAfter.timeType,
678 validity->notAfter.time.Data);
679
680 if (ret == -1)
681 return (KMF_ERR_BAD_CERT_FORMAT);
682
683 return (KMF_OK);
684 }
685
686 static KMF_RETURN
get_validity(BerElement * asn1,KMF_X509_VALIDITY * validity)687 get_validity(BerElement *asn1, KMF_X509_VALIDITY *validity)
688 {
689 KMF_RETURN ret = KMF_OK;
690 int tag;
691 int t1, t2;
692 ber_len_t size;
693 char *t1str, *t2str;
694
695 (void) memset(validity, 0, sizeof (KMF_X509_VALIDITY));
696
697 tag = kmfber_next_element(asn1, &size, NULL);
698 if (tag != BER_CONSTRUCTED_SEQUENCE) {
699 return (KMF_ERR_BAD_CERT_FORMAT);
700 }
701
702 if (kmfber_scanf(asn1, "{tata}", &t1, &t1str, &t2, &t2str) == -1) {
703 return (KMF_ERR_BAD_CERT_FORMAT);
704 }
705
706 validity->notBefore.timeType = t1;
707 validity->notBefore.time.Data = (uchar_t *)t1str;
708 validity->notBefore.time.Length = strlen(t1str);
709
710 validity->notAfter.timeType = t2;
711 validity->notAfter.time.Data = (uchar_t *)t2str;
712 validity->notAfter.time.Length = strlen(t2str);
713
714 return (ret);
715 }
716
717 KMF_RETURN
AddRDN(KMF_X509_NAME * name,KMF_X509_RDN * newrdn)718 AddRDN(KMF_X509_NAME *name, KMF_X509_RDN *newrdn)
719 {
720 KMF_RETURN ret = KMF_OK;
721 KMF_X509_RDN *rdnslot = NULL;
722
723 /* Add new RDN record to existing list */
724 name->numberOfRDNs++;
725 name->RelativeDistinguishedName =
726 realloc(name->RelativeDistinguishedName,
727 name->numberOfRDNs * sizeof (KMF_X509_RDN));
728
729 if (name->RelativeDistinguishedName == NULL) {
730 ret = KMF_ERR_MEMORY;
731 goto cleanup;
732 }
733 rdnslot = &name->RelativeDistinguishedName[name->numberOfRDNs-1];
734
735 if (newrdn) {
736 (void) memcpy(rdnslot, newrdn, sizeof (KMF_X509_RDN));
737 } else {
738 rdnslot->numberOfPairs = 0;
739 rdnslot->AttributeTypeAndValue = NULL;
740 }
741
742 cleanup:
743 /* No cleanup needed here */
744 return (ret);
745 }
746
747 static KMF_RETURN
encode_rdn(BerElement * asn1,KMF_X509_NAME * name)748 encode_rdn(BerElement *asn1, KMF_X509_NAME *name)
749 {
750 KMF_RETURN ret = KMF_OK;
751 KMF_X509_TYPE_VALUE_PAIR *attrtvpair = NULL;
752 int i;
753 KMF_X509_RDN *rdn;
754
755 if (kmfber_printf(asn1, "{") == -1) {
756 ret = KMF_ERR_MEMORY;
757 goto cleanup;
758 }
759
760 for (i = 0; i < name->numberOfRDNs; i++) {
761 if (kmfber_printf(asn1, "[") == -1) {
762 ret = KMF_ERR_MEMORY;
763 goto cleanup;
764 }
765 rdn = &name->RelativeDistinguishedName[i];
766 attrtvpair = rdn->AttributeTypeAndValue;
767
768 if (rdn->numberOfPairs > 0) {
769 if (kmfber_printf(asn1, "{Dto}",
770 &attrtvpair->type,
771 attrtvpair->valueType,
772 attrtvpair->value.Data,
773 attrtvpair->value.Length) == -1) {
774 ret = KMF_ERR_MEMORY;
775 goto cleanup;
776 }
777 }
778 if (kmfber_printf(asn1, "]") == -1) {
779 ret = KMF_ERR_MEMORY;
780 goto cleanup;
781 }
782 }
783
784 if (kmfber_printf(asn1, "}") == -1) {
785 ret = KMF_ERR_MEMORY;
786 goto cleanup;
787 }
788
789 cleanup:
790 /* No cleanup needed here */
791
792 return (ret);
793 }
794
795
796 KMF_RETURN
CopyRDN(KMF_X509_NAME * srcname,KMF_X509_NAME ** destname)797 CopyRDN(KMF_X509_NAME *srcname, KMF_X509_NAME **destname)
798 {
799 KMF_RETURN ret = KMF_OK;
800 KMF_X509_NAME *newname = NULL;
801 KMF_X509_RDN *rdn, *dstrdn;
802 KMF_X509_TYPE_VALUE_PAIR *av = NULL;
803 KMF_X509_TYPE_VALUE_PAIR *srcav = NULL;
804 KMF_X509_TYPE_VALUE_PAIR *dstav = NULL;
805 int i, j;
806
807 newname = malloc(sizeof (KMF_X509_NAME));
808 if (newname == NULL)
809 return (KMF_ERR_MEMORY);
810 (void) memset(newname, 0, sizeof (KMF_X509_NAME));
811
812 newname->numberOfRDNs = srcname->numberOfRDNs;
813 newname->RelativeDistinguishedName = malloc(newname->numberOfRDNs *
814 sizeof (KMF_X509_RDN));
815 if (newname->RelativeDistinguishedName == NULL) {
816 free(newname);
817 return (KMF_ERR_MEMORY);
818 }
819 /* Copy each RDN in the list */
820 for (i = 0; i < newname->numberOfRDNs; i++) {
821 rdn = &srcname->RelativeDistinguishedName[i];
822
823 dstrdn = &newname->RelativeDistinguishedName[i];
824 (void) memset(dstrdn, 0, sizeof (KMF_X509_RDN));
825
826 dstrdn->numberOfPairs = rdn->numberOfPairs;
827 if (dstrdn->numberOfPairs > 0) {
828 av = malloc(dstrdn->numberOfPairs *
829 sizeof (KMF_X509_TYPE_VALUE_PAIR));
830 if (av == NULL) {
831 ret = KMF_ERR_MEMORY;
832 goto cleanup;
833 }
834 (void) memset(av, 0, dstrdn->numberOfPairs *
835 sizeof (KMF_X509_TYPE_VALUE_PAIR));
836
837 dstrdn->AttributeTypeAndValue = av;
838 if (av == NULL) {
839 ret = KMF_ERR_MEMORY;
840 goto cleanup;
841 }
842 /* Copy each A/V pair in the list */
843 for (j = 0; j < dstrdn->numberOfPairs; j++) {
844 srcav = &rdn->AttributeTypeAndValue[j];
845 dstav = &dstrdn->AttributeTypeAndValue[j];
846 if ((ret = CopyData(&srcav->type,
847 &dstav->type)) != KMF_OK)
848 goto cleanup;
849 dstav->valueType = srcav->valueType;
850 if ((ret = CopyData(&srcav->value,
851 &dstav->value)) != KMF_OK)
852 goto cleanup;
853 }
854 } else {
855 dstrdn->AttributeTypeAndValue = NULL;
856 }
857 }
858 *destname = newname;
859
860 cleanup:
861 if (ret != KMF_OK) {
862 if (newname)
863 free_rdn_data(newname);
864
865 free(newname);
866 *destname = NULL;
867 }
868 return (ret);
869 }
870
871 #define VALID_DIRECTORYSTRING_TAG(t) ( \
872 (t == BER_UTF8_STRING) || \
873 (t == BER_PRINTABLE_STRING) || \
874 (t == BER_IA5STRING) || \
875 (t == BER_T61STRING) || \
876 (t == BER_BMP_STRING) || \
877 (t == BER_UNIVERSAL_STRING))
878
879 static KMF_RETURN
get_rdn(BerElement * asn1,KMF_X509_NAME * name)880 get_rdn(BerElement *asn1, KMF_X509_NAME *name)
881 {
882 KMF_RETURN ret = KMF_OK;
883 ber_len_t size;
884 char *end;
885 int tag;
886 BerValue AttrOID;
887 char *AttrValue = NULL;
888 KMF_X509_TYPE_VALUE_PAIR *newpair = NULL;
889 KMF_X509_RDN newrdn;
890
891 /*
892 * AttributeType ::= OBJECT IDENTIFIER
893 * AttributeValue ::= ANY
894 *
895 * AttributeTypeAndValue ::= SEQUENCE {
896 * type AttributeType,
897 * value AttributeValue }
898 *
899 * Name ::= CHOICE { -- only one possibility for now --
900 * rdnSequence RDNSequence }
901 *
902 * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
903 *
904 * DistinguishedName ::= RDNSequence
905 *
906 * RelativeDistinguishedName ::=
907 * SET SIZE (1 .. MAX) OF AttributeTypeAndValue
908 *
909 */
910
911 name->numberOfRDNs = 0;
912 name->RelativeDistinguishedName = NULL;
913
914 /* Get the beginning of the RDN Set and a ptr to the end */
915 tag = kmfber_first_element(asn1, &size, &end);
916 if (tag != BER_CONSTRUCTED_SET) {
917 goto cleanup;
918 }
919
920 /* Walk through the individual SET items until the "end" is reached */
921 while ((tag = kmfber_next_element(asn1, &size, end)) ==
922 BER_CONSTRUCTED_SET) {
923 /* Skip over the SET tag */
924 if (kmfber_scanf(asn1, "T", &tag) == -1) {
925 ret = KMF_ERR_BAD_CERT_FORMAT;
926 break;
927 }
928
929 /* An "empty" set member means we tack on an empty node */
930 if (size == 0) {
931 if ((ret = AddRDN(name, NULL)) != KMF_OK)
932 goto cleanup;
933 continue;
934 }
935
936 /* Attr OID and peek at the next tag and field length */
937 if (kmfber_scanf(asn1, "{Dtl", &AttrOID, &tag, &size) == -1) {
938 ret = KMF_ERR_BAD_CERT_FORMAT;
939 break;
940 }
941
942 if (!(VALID_DIRECTORYSTRING_TAG(tag))) {
943 ret = KMF_ERR_BAD_CERT_FORMAT;
944 break;
945 }
946
947 if (kmfber_scanf(asn1, "a}]", &AttrValue) == -1) {
948 ret = KMF_ERR_BAD_CERT_FORMAT;
949 break;
950 }
951
952 /* Allocate a new name/value pair record */
953 newpair = malloc(sizeof (KMF_X509_TYPE_VALUE_PAIR));
954 if (newpair == NULL) {
955 ret = KMF_ERR_MEMORY;
956 break;
957 }
958 (void) memset(newpair, 0, sizeof (KMF_X509_TYPE_VALUE_PAIR));
959 newpair->type.Data = (uchar_t *)AttrOID.bv_val;
960 newpair->type.Length = AttrOID.bv_len;
961 newpair->valueType = tag; /* what kind of string is it? */
962 newpair->value.Data = (uchar_t *)AttrValue;
963 newpair->value.Length = strlen(AttrValue);
964
965 (void) memset(&newrdn, 0, sizeof (KMF_X509_RDN));
966 newrdn.numberOfPairs = 1;
967 newrdn.AttributeTypeAndValue = newpair;
968
969 if ((ret = AddRDN(name, &newrdn)) != KMF_OK)
970 break;
971 }
972
973 cleanup:
974 if (ret != KMF_OK) {
975 free_rdn_data(name);
976 }
977 return (ret);
978 }
979
980 static KMF_RETURN
set_der_integer(KMF_DATA * data,int value)981 set_der_integer(KMF_DATA *data, int value)
982 {
983 if (data == NULL)
984 return (KMF_ERR_BAD_PARAMETER);
985
986 data->Data = malloc(sizeof (int));
987 if (data->Data == NULL)
988 return (KMF_ERR_MEMORY);
989
990 data->Length = sizeof (int);
991 (void) memcpy((void *)data->Data, (const void *)&value, sizeof (int));
992
993 return (KMF_OK);
994 }
995
996 static KMF_RETURN
set_bigint(KMF_BIGINT * data,KMF_BIGINT * bigint)997 set_bigint(KMF_BIGINT *data, KMF_BIGINT *bigint)
998 {
999 if (data == NULL || bigint == NULL)
1000 return (KMF_ERR_BAD_PARAMETER);
1001
1002 data->val = malloc(bigint->len);
1003 if (data->val == NULL)
1004 return (KMF_ERR_MEMORY);
1005
1006 data->len = bigint->len;
1007 (void) memcpy((void *)data->val, (const void *)bigint->val,
1008 bigint->len);
1009
1010 return (KMF_OK);
1011 }
1012
1013 static KMF_RETURN
encode_uniqueid(BerElement * asn1,int tag,KMF_DATA * id)1014 encode_uniqueid(BerElement *asn1, int tag, KMF_DATA *id)
1015 {
1016 KMF_RETURN ret = KMF_OK;
1017 uint32_t len;
1018
1019 len = kmfber_calc_taglen(BER_BIT_STRING) +
1020 kmfber_calc_lenlen(id->Length * 8) + id->Length;
1021 if (kmfber_printf(asn1, "TlB", tag, len,
1022 id->Data, id->Length * 8) == -1)
1023 return (KMF_ERR_BAD_CERT_FORMAT);
1024
1025 return (ret);
1026 }
1027
1028 static KMF_RETURN
encode_extension_list(BerElement * asn1,KMF_X509_EXTENSIONS * extns)1029 encode_extension_list(BerElement *asn1, KMF_X509_EXTENSIONS *extns)
1030 {
1031 KMF_RETURN ret = KMF_OK;
1032 int i;
1033
1034 for (i = 0; i < extns->numberOfExtensions; i++) {
1035 BerValue v;
1036 v.bv_val = (char *)extns->extensions[i].extnId.Data;
1037 v.bv_len = extns->extensions[i].extnId.Length;
1038
1039 if (kmfber_printf(asn1, "{D", &v) == -1) {
1040 ret = KMF_ERR_ENCODING;
1041 goto cleanup;
1042 }
1043
1044 if (extns->extensions[i].critical) {
1045 if (kmfber_printf(asn1, "b",
1046 extns->extensions[i].critical) == -1) {
1047 ret = KMF_ERR_ENCODING;
1048 goto cleanup;
1049 }
1050 }
1051
1052 if (kmfber_printf(asn1, "o}",
1053 extns->extensions[i].BERvalue.Data,
1054 extns->extensions[i].BERvalue.Length) == -1) {
1055 ret = KMF_ERR_ENCODING;
1056 goto cleanup;
1057 }
1058 }
1059 cleanup:
1060 return (ret);
1061 }
1062
1063 static KMF_RETURN
encode_extensions(BerElement * asn1,KMF_X509_EXTENSIONS * extns)1064 encode_extensions(BerElement *asn1, KMF_X509_EXTENSIONS *extns)
1065 {
1066 KMF_RETURN ret = KMF_OK;
1067 BerElement *extn = NULL;
1068 BerValue *extnvalue = NULL;
1069
1070 extn = kmfder_alloc();
1071 if (extn == NULL)
1072 return (KMF_ERR_MEMORY);
1073
1074 if (kmfber_printf(extn, "{") == -1) {
1075 ret = KMF_ERR_ENCODING;
1076 goto cleanup;
1077 }
1078
1079 ret = encode_extension_list(extn, extns);
1080
1081 if (kmfber_printf(extn, "}") == -1) {
1082 ret = KMF_ERR_ENCODING;
1083 goto cleanup;
1084 }
1085
1086 if (kmfber_flatten(extn, &extnvalue) == -1) {
1087 ret = KMF_ERR_MEMORY;
1088 goto cleanup;
1089 }
1090
1091 if (kmfber_printf(asn1, "Tl", 0xA3, extnvalue->bv_len) == -1) {
1092 ret = KMF_ERR_BAD_CERT_FORMAT;
1093 goto cleanup;
1094 }
1095
1096 if (kmfber_write(asn1, extnvalue->bv_val, extnvalue->bv_len, 0) == -1) {
1097 ret = KMF_ERR_BAD_CERT_FORMAT;
1098 goto cleanup;
1099 }
1100
1101 cleanup:
1102 kmfber_free(extn, 1);
1103 if (extnvalue != NULL)
1104 kmfber_bvfree(extnvalue);
1105
1106 return (ret);
1107 }
1108
1109 static KMF_RETURN
get_one_extension(BerElement * asn1,KMF_X509_EXTENSION ** retex,char * end)1110 get_one_extension(BerElement *asn1, KMF_X509_EXTENSION **retex, char *end)
1111 {
1112 KMF_RETURN ret = KMF_OK;
1113 ber_len_t size;
1114 int critical, tag;
1115 KMF_X509_EXTENSION *ex = NULL;
1116 BerValue extOID;
1117 BerValue extValue;
1118 BerElement *extnber = NULL;
1119
1120 if (kmfber_scanf(asn1, "T", &tag) == -1) {
1121 ret = KMF_ERR_BAD_CERT_FORMAT;
1122 goto cleanup;
1123 }
1124
1125 tag = kmfber_next_element(asn1, &size, end);
1126 if (tag != BER_OBJECT_IDENTIFIER) {
1127 ret = KMF_ERR_BAD_CERT_FORMAT;
1128 goto cleanup;
1129 }
1130 if (kmfber_scanf(asn1, "D", &extOID) == -1) {
1131 ret = KMF_ERR_BAD_CERT_FORMAT;
1132 goto cleanup;
1133 }
1134
1135 tag = kmfber_next_element(asn1, &size, end);
1136 if (tag != BER_BOOLEAN) {
1137 critical = 0;
1138 if (tag != BER_OCTET_STRING)
1139 goto cleanup;
1140 } else {
1141 if (kmfber_scanf(asn1, "b", &critical) == -1)
1142 goto cleanup;
1143 }
1144
1145 tag = kmfber_next_element(asn1, &size, end);
1146 if (tag != BER_OCTET_STRING) {
1147 ret = KMF_ERR_BAD_CERT_FORMAT;
1148 goto cleanup;
1149 }
1150 if (kmfber_scanf(asn1, "o", &extValue) == -1) {
1151 ret = KMF_ERR_BAD_CERT_FORMAT;
1152 goto cleanup;
1153 }
1154
1155 /* allocate a new Extension record */
1156 ex = malloc(sizeof (KMF_X509_EXTENSION));
1157 if (ex == NULL) {
1158 ret = KMF_ERR_MEMORY;
1159 goto cleanup;
1160 }
1161 (void) memset(ex, 0, sizeof (ex));
1162
1163 ex->extnId.Data = (uchar_t *)extOID.bv_val;
1164 ex->extnId.Length = extOID.bv_len;
1165 ex->critical = critical;
1166 ex->format = KMF_X509_DATAFORMAT_ENCODED;
1167 ex->BERvalue.Data = (uchar_t *)extValue.bv_val;
1168 ex->BERvalue.Length = extValue.bv_len;
1169
1170 /* Tag and value is a little tricky */
1171 ex->value.tagAndValue = malloc(sizeof (KMF_X509EXT_TAGandVALUE));
1172 if (ex->value.tagAndValue == NULL) {
1173 ret = KMF_ERR_MEMORY;
1174 goto cleanup;
1175 }
1176 (void) memset(ex->value.tagAndValue, 0,
1177 sizeof (KMF_X509EXT_TAGandVALUE));
1178
1179 /* Parse the Extension value field */
1180 extnber = kmfder_init(&extValue);
1181 if (extnber == NULL) {
1182 ret = KMF_ERR_MEMORY;
1183 goto cleanup;
1184 }
1185
1186 /* Get the tag and length of the extension field */
1187 if (kmfber_scanf(extnber, "tl", &tag, &size) == -1) {
1188 ret = KMF_ERR_BAD_CERT_FORMAT;
1189 goto cleanup;
1190 }
1191
1192 if (kmfber_scanf(extnber, "T", &tag) == -1) {
1193 ret = KMF_ERR_BAD_CERT_FORMAT;
1194 goto cleanup;
1195 }
1196
1197 ex->value.tagAndValue->value.Data = malloc(size);
1198 ex->value.tagAndValue->value.Length = size;
1199 size = kmfber_read(extnber,
1200 (char *)ex->value.tagAndValue->value.Data, size);
1201 if (size != ex->value.tagAndValue->value.Length) {
1202 ret = KMF_ERR_BAD_CERT_FORMAT;
1203 goto cleanup;
1204 }
1205 kmfber_free(extnber, 1);
1206 ex->value.tagAndValue->type = tag;
1207
1208 *retex = ex;
1209 cleanup:
1210 if (ret != KMF_OK) {
1211 if (ex != NULL)
1212 free_one_extension(ex);
1213 }
1214
1215 return (ret);
1216 }
1217
1218 static KMF_RETURN
get_extensions(BerElement * asn1,KMF_X509_EXTENSIONS * extns)1219 get_extensions(BerElement *asn1, KMF_X509_EXTENSIONS *extns)
1220 {
1221 KMF_RETURN ret = KMF_OK;
1222 ber_len_t size;
1223 char *end = NULL;
1224 KMF_X509_EXTENSION *ex = NULL;
1225
1226 /*
1227 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
1228 *
1229 * Extension ::= SEQUENCE {
1230 * extnID OBJECT IDENTIFIER,
1231 * critical BOOLEAN DEFAULT FALSE,
1232 * extnValue OCTET STRING }
1233 *
1234 * { {{D}Bo}, ... }
1235 */
1236 if (kmfber_first_element(asn1, &size, &end) !=
1237 BER_CONSTRUCTED_SEQUENCE)
1238 return (KMF_ERR_BAD_CERT_FORMAT);
1239
1240 while (kmfber_next_element(asn1, &size, end) ==
1241 BER_CONSTRUCTED_SEQUENCE) {
1242 ret = get_one_extension(asn1, &ex, end);
1243 if (ret != KMF_OK)
1244 goto cleanup;
1245
1246 extns->numberOfExtensions++;
1247 extns->extensions = realloc(extns->extensions,
1248 extns->numberOfExtensions *
1249 sizeof (KMF_X509_EXTENSION));
1250 if (extns->extensions == NULL) {
1251 ret = KMF_ERR_MEMORY;
1252 break;
1253 }
1254
1255 extns->extensions[extns->numberOfExtensions-1] = *ex;
1256 free(ex);
1257 }
1258
1259 cleanup:
1260 if (ret != KMF_OK)
1261 free_extensions(extns);
1262
1263 return (ret);
1264 }
1265
1266 KMF_RETURN
decode_tbscert_data(BerElement * asn1,KMF_X509_TBS_CERT ** signed_cert_ptr_ptr)1267 decode_tbscert_data(BerElement *asn1,
1268 KMF_X509_TBS_CERT **signed_cert_ptr_ptr)
1269 {
1270 KMF_RETURN ret = KMF_OK;
1271 KMF_X509_TBS_CERT *tbscert = NULL;
1272 int tag, version;
1273 struct berval *bvserno = NULL;
1274 KMF_BIGINT serno;
1275
1276 if (kmfber_scanf(asn1, "{t", &tag) == -1) {
1277 ret = KMF_ERR_BAD_CERT_FORMAT;
1278 goto cleanup;
1279 }
1280
1281 /* Version number is optional */
1282 if (tag == 0xA0) {
1283 if (kmfber_scanf(asn1, "Ti", &tag, &version) == -1) {
1284 ret = KMF_ERR_BAD_CERT_FORMAT;
1285 goto cleanup;
1286 }
1287 } else {
1288 version = 0; /* DEFAULT v1 (0) */
1289 }
1290
1291 /* Now get the serial number, it is not optional */
1292 if (kmfber_scanf(asn1, "I", &bvserno) == -1) {
1293 ret = KMF_ERR_BAD_CERT_FORMAT;
1294 goto cleanup;
1295 } else {
1296 serno.val = (uchar_t *)bvserno->bv_val;
1297 serno.len = bvserno->bv_len;
1298 }
1299
1300 tbscert = malloc(sizeof (KMF_X509_TBS_CERT));
1301 if (!tbscert) {
1302 ret = KMF_ERR_MEMORY;
1303 goto cleanup;
1304 }
1305
1306 (void) memset(tbscert, 0, sizeof (KMF_X509_TBS_CERT));
1307
1308 if ((ret = set_der_integer(&tbscert->version, version)) != KMF_OK)
1309 goto cleanup;
1310
1311 if ((ret = set_bigint(&tbscert->serialNumber, &serno)) != KMF_OK)
1312 goto cleanup;
1313
1314 if ((ret = get_algoid(asn1, &tbscert->signature)) != KMF_OK)
1315 goto cleanup;
1316
1317 if ((ret = get_rdn(asn1, &tbscert->issuer)) != KMF_OK)
1318 goto cleanup;
1319
1320 if ((ret = get_validity(asn1, &tbscert->validity)) != KMF_OK)
1321 goto cleanup;
1322
1323 if ((ret = get_rdn(asn1, &tbscert->subject)) != KMF_OK)
1324 goto cleanup;
1325
1326 if ((ret = get_spki(asn1, &tbscert->subjectPublicKeyInfo)) != KMF_OK)
1327 goto cleanup;
1328
1329 /* Check for the optional fields */
1330 tbscert->extensions.numberOfExtensions = 0;
1331 tbscert->extensions.extensions = NULL;
1332
1333 while ((kmfber_scanf(asn1, "t", &tag)) != -1 &&
1334 (tag == 0xA1 || tag == 0xA2 || tag == 0xA3)) {
1335 char *optfield;
1336 ber_len_t len;
1337
1338 /* consume the tag and length */
1339 (void) kmfber_scanf(asn1, "T", &tag);
1340 switch (tag) {
1341 case 0xA1:
1342 if (kmfber_scanf(asn1, "B", &optfield, &len) !=
1343 BER_BIT_STRING) {
1344 ret = KMF_ERR_BAD_CERT_FORMAT;
1345 goto cleanup;
1346 }
1347 tbscert->issuerUniqueIdentifier.Data =
1348 (uchar_t *)optfield;
1349 tbscert->issuerUniqueIdentifier.Length =
1350 len / 8;
1351 break;
1352 case 0xA2:
1353 if (kmfber_scanf(asn1, "B", &optfield, &len) !=
1354 BER_BIT_STRING) {
1355 ret = KMF_ERR_BAD_CERT_FORMAT;
1356 goto cleanup;
1357 }
1358 tbscert->subjectUniqueIdentifier.Data =
1359 (uchar_t *)optfield;
1360 tbscert->subjectUniqueIdentifier.Length =
1361 len / 8;
1362 break;
1363 case 0xA3:
1364 ret = get_extensions(asn1, &tbscert->extensions);
1365 break;
1366 }
1367 }
1368
1369 *signed_cert_ptr_ptr = tbscert;
1370
1371 cleanup:
1372 if (bvserno != NULL) {
1373 free(bvserno->bv_val);
1374 free(bvserno);
1375 }
1376 if (ret != KMF_OK) {
1377 if (tbscert) {
1378 free_tbscert(tbscert);
1379 free(tbscert);
1380 }
1381 *signed_cert_ptr_ptr = NULL;
1382 }
1383 return (ret);
1384 }
1385
1386 KMF_RETURN
DerDecodeTbsCertificate(const KMF_DATA * Value,KMF_X509_TBS_CERT ** tbscert)1387 DerDecodeTbsCertificate(const KMF_DATA *Value,
1388 KMF_X509_TBS_CERT **tbscert)
1389 {
1390 KMF_RETURN ret = KMF_OK;
1391 BerElement *asn1 = NULL;
1392 BerValue rawcert;
1393 KMF_X509_TBS_CERT *newcert = NULL;
1394
1395 if (!tbscert || !Value || !Value->Data || !Value->Length)
1396 return (KMF_ERR_BAD_PARAMETER);
1397
1398 rawcert.bv_val = (char *)Value->Data;
1399 rawcert.bv_len = Value->Length;
1400
1401 if ((asn1 = kmfder_init(&rawcert)) == NULL)
1402 return (KMF_ERR_MEMORY);
1403
1404 ret = decode_tbscert_data(asn1, &newcert);
1405 if (ret != KMF_OK)
1406 goto cleanup;
1407
1408 *tbscert = newcert;
1409
1410 cleanup:
1411 if (ret != KMF_OK) {
1412 if (newcert)
1413 free_tbscert(newcert);
1414 *tbscert = NULL;
1415 }
1416 kmfber_free(asn1, 1);
1417
1418 return (ret);
1419 }
1420
1421 /*
1422 * Name: DerDecodeSignedCertificate
1423 *
1424 * Description:
1425 * DER decodes the encoded X509 certificate
1426 *
1427 * Parameters:
1428 * Value (input): DER encoded object that shd be decoded
1429 *
1430 * signed_cert_ptr_ptr (output) : Decoded KMF_X509_CERTIFICATE object
1431 */
1432 KMF_RETURN
DerDecodeSignedCertificate(const KMF_DATA * Value,KMF_X509_CERTIFICATE ** signed_cert_ptr_ptr)1433 DerDecodeSignedCertificate(const KMF_DATA *Value,
1434 KMF_X509_CERTIFICATE **signed_cert_ptr_ptr)
1435 {
1436 KMF_RETURN ret = KMF_OK;
1437 BerElement *asn1 = NULL;
1438 BerValue rawcert;
1439 ber_tag_t tag;
1440 ber_len_t size;
1441 char *end = NULL;
1442 char *signature;
1443 KMF_X509_TBS_CERT *tbscert = NULL;
1444 KMF_X509_CERTIFICATE *certptr = NULL;
1445
1446 if (!signed_cert_ptr_ptr || !Value || !Value->Data || !Value->Length)
1447 return (KMF_ERR_BAD_PARAMETER);
1448
1449 rawcert.bv_val = (char *)Value->Data;
1450 rawcert.bv_len = Value->Length;
1451
1452 if ((asn1 = kmfder_init(&rawcert)) == NULL)
1453 return (KMF_ERR_MEMORY);
1454
1455 if (kmfber_first_element(asn1, &size, &end) !=
1456 BER_CONSTRUCTED_SEQUENCE) {
1457 ret = KMF_ERR_BAD_CERT_FORMAT;
1458 goto cleanup;
1459 }
1460
1461 certptr = malloc(sizeof (KMF_X509_CERTIFICATE));
1462 if (certptr == NULL) {
1463 ret = KMF_ERR_MEMORY;
1464 goto cleanup;
1465 }
1466 (void) memset(certptr, 0, sizeof (KMF_X509_CERTIFICATE));
1467
1468 ret = decode_tbscert_data(asn1, &tbscert);
1469 if (ret != KMF_OK)
1470 goto cleanup;
1471
1472 certptr->certificate = *tbscert;
1473 free(tbscert);
1474 tbscert = NULL;
1475
1476 /*
1477 * The signature data my not be present yet.
1478 */
1479 if ((ret = get_algoid(asn1,
1480 &certptr->signature.algorithmIdentifier)) == KMF_OK) {
1481
1482 /* Check to see if the cert has a signature yet */
1483 if (kmfber_next_element(asn1, &size, end) == BER_BIT_STRING) {
1484 /* Finally, get the encrypted signature BITSTRING */
1485 if (kmfber_scanf(asn1, "tl", &tag, &size) == -1) {
1486 ret = KMF_ERR_BAD_CERT_FORMAT;
1487 goto cleanup;
1488 }
1489 if (tag != BER_BIT_STRING) {
1490 ret = KMF_ERR_BAD_CERT_FORMAT;
1491 goto cleanup;
1492 }
1493 if (kmfber_scanf(asn1, "B}", &signature, &size) == -1) {
1494 ret = KMF_ERR_BAD_CERT_FORMAT;
1495 goto cleanup;
1496 }
1497 certptr->signature.encrypted.Data =
1498 (uchar_t *)signature;
1499 certptr->signature.encrypted.Length = size / 8;
1500 } else {
1501 certptr->signature.encrypted.Data = NULL;
1502 certptr->signature.encrypted.Length = 0;
1503 }
1504 } else {
1505 (void) memset(&certptr->signature, 0,
1506 sizeof (certptr->signature));
1507 ret = KMF_OK;
1508 }
1509
1510 *signed_cert_ptr_ptr = certptr;
1511 cleanup:
1512 if (ret != KMF_OK) {
1513 if (certptr) {
1514 free_decoded_cert(certptr);
1515 free(certptr);
1516 }
1517
1518 *signed_cert_ptr_ptr = NULL;
1519 }
1520 if (asn1)
1521 kmfber_free(asn1, 1);
1522
1523 return (ret);
1524
1525 }
1526
1527 KMF_RETURN
DerDecodeExtension(KMF_DATA * Data,KMF_X509_EXTENSION ** extn)1528 DerDecodeExtension(KMF_DATA *Data, KMF_X509_EXTENSION **extn)
1529 {
1530 KMF_RETURN ret = KMF_OK;
1531 BerElement *asn1 = NULL;
1532 BerValue bv;
1533
1534 bv.bv_val = (char *)Data->Data;
1535 bv.bv_len = Data->Length;
1536
1537 asn1 = kmfder_init(&bv);
1538 if (asn1 == NULL)
1539 return (KMF_ERR_MEMORY);
1540
1541 ret = get_one_extension(asn1, extn, NULL);
1542
1543 if (ret != KMF_OK) {
1544 if (*extn != NULL) {
1545 free(*extn);
1546 }
1547 *extn = NULL;
1548 }
1549
1550 kmfber_free(asn1, 1);
1551 return (ret);
1552 }
1553
1554 KMF_RETURN
DerDecodeName(KMF_DATA * encodedname,KMF_X509_NAME * name)1555 DerDecodeName(KMF_DATA *encodedname, KMF_X509_NAME *name)
1556 {
1557 KMF_RETURN ret = KMF_OK;
1558 BerElement *asn1 = NULL;
1559 BerValue bv;
1560
1561 bv.bv_val = (char *)encodedname->Data;
1562 bv.bv_len = encodedname->Length;
1563
1564 asn1 = kmfder_init(&bv);
1565 if (asn1 == NULL)
1566 return (KMF_ERR_MEMORY);
1567
1568 (void) memset((void *)name, 0, sizeof (KMF_X509_NAME));
1569
1570 if ((ret = get_rdn(asn1, name)) != KMF_OK)
1571 goto cleanup;
1572
1573 cleanup:
1574 if (asn1)
1575 kmfber_free(asn1, 1);
1576 return (ret);
1577 }
1578
1579 KMF_RETURN
DerEncodeName(KMF_X509_NAME * name,KMF_DATA * encodedname)1580 DerEncodeName(KMF_X509_NAME *name, KMF_DATA *encodedname)
1581 {
1582 KMF_RETURN ret = KMF_OK;
1583 BerElement *asn1 = NULL;
1584 BerValue *bv = NULL;
1585
1586 asn1 = kmfder_alloc();
1587 if (asn1 == NULL)
1588 return (KMF_ERR_MEMORY);
1589
1590 if ((ret = encode_rdn(asn1, name)) != KMF_OK)
1591 goto cleanup;
1592
1593 if (kmfber_flatten(asn1, &bv) == -1) {
1594 ret = KMF_ERR_BAD_CERT_FORMAT;
1595 goto cleanup;
1596 }
1597
1598 encodedname->Data = (uchar_t *)bv->bv_val;
1599 encodedname->Length = bv->bv_len;
1600
1601 cleanup:
1602 if (bv)
1603 free(bv);
1604
1605 if (asn1)
1606 kmfber_free(asn1, 1);
1607
1608 return (ret);
1609 }
1610
1611 static KMF_RETURN
encode_tbs_cert(BerElement * asn1,KMF_X509_TBS_CERT * tbscert)1612 encode_tbs_cert(BerElement *asn1, KMF_X509_TBS_CERT *tbscert)
1613 {
1614 KMF_RETURN ret = KMF_OK;
1615 uint32_t version;
1616
1617 /* version should be 4 bytes or less */
1618 if (tbscert->version.Length > sizeof (int))
1619 return (KMF_ERR_BAD_CERT_FORMAT);
1620
1621 (void) memcpy(&version, tbscert->version.Data,
1622 tbscert->version.Length);
1623
1624 /* Start the sequence and add the version */
1625 if (kmfber_printf(asn1, "{Tli", 0xA0, 3, version) == -1) {
1626 ret = KMF_ERR_BAD_CERT_FORMAT;
1627 goto cleanup;
1628 }
1629 /* Write the serial number */
1630 if (kmfber_printf(asn1, "I",
1631 (char *)tbscert->serialNumber.val,
1632 (size_t)tbscert->serialNumber.len) == -1) {
1633 ret = KMF_ERR_BAD_CERT_FORMAT;
1634 goto cleanup;
1635 }
1636
1637 /* Don't encode alg parameters in signature algid area */
1638 if ((ret = encode_algoid(asn1, &tbscert->signature, FALSE)) != KMF_OK)
1639 goto cleanup;
1640
1641 /* Encode the Issuer RDN */
1642 if ((ret = encode_rdn(asn1, &tbscert->issuer)) != KMF_OK)
1643 goto cleanup;
1644
1645 /* Encode the Validity fields */
1646 if ((ret = encode_validity(asn1, &tbscert->validity)) != KMF_OK)
1647 goto cleanup;
1648
1649 /* Encode the Subject RDN */
1650 if ((ret = encode_rdn(asn1, &tbscert->subject)) != KMF_OK)
1651 goto cleanup;
1652
1653 /* Encode the Subject Public Key Info */
1654 if ((ret = encode_spki(asn1, &tbscert->subjectPublicKeyInfo)) != KMF_OK)
1655 goto cleanup;
1656
1657 /* Optional field: issuer Unique ID */
1658 if (tbscert->issuerUniqueIdentifier.Length > 0) {
1659 if ((ret = encode_uniqueid(asn1, 0xA1,
1660 &tbscert->issuerUniqueIdentifier)) != KMF_OK)
1661 goto cleanup;
1662 }
1663
1664 /* Optional field: Subject Unique ID */
1665 if (tbscert->subjectUniqueIdentifier.Length > 0) {
1666 if ((ret = encode_uniqueid(asn1, 0xA2,
1667 &tbscert->subjectUniqueIdentifier)) != KMF_OK)
1668 goto cleanup;
1669 }
1670
1671 /* Optional field: Certificate Extensions */
1672 if (tbscert->extensions.numberOfExtensions > 0) {
1673 if ((ret = encode_extensions(asn1,
1674 &tbscert->extensions)) != KMF_OK)
1675 goto cleanup;
1676 }
1677
1678 /* Close out the TBSCert sequence */
1679 if (kmfber_printf(asn1, "}") == -1) {
1680 ret = KMF_ERR_BAD_CERT_FORMAT;
1681 goto cleanup;
1682 }
1683
1684 cleanup:
1685 /*
1686 * Memory cleanup is done in the caller or in the individual
1687 * encoding routines.
1688 */
1689
1690 return (ret);
1691 }
1692
1693 KMF_RETURN
DerEncodeTbsCertificate(KMF_X509_TBS_CERT * tbs_cert_ptr,KMF_DATA * enc_tbs_cert_ptr)1694 DerEncodeTbsCertificate(KMF_X509_TBS_CERT *tbs_cert_ptr,
1695 KMF_DATA *enc_tbs_cert_ptr)
1696 {
1697 KMF_RETURN ret;
1698 BerElement *asn1 = NULL;
1699 BerValue *tbsdata = NULL;
1700
1701 asn1 = kmfder_alloc();
1702 if (asn1 == NULL)
1703 return (KMF_ERR_MEMORY);
1704
1705 enc_tbs_cert_ptr->Data = NULL;
1706 enc_tbs_cert_ptr->Length = 0;
1707
1708 ret = encode_tbs_cert(asn1, tbs_cert_ptr);
1709 if (ret != KMF_OK)
1710 goto cleanup;
1711
1712 if (kmfber_flatten(asn1, &tbsdata) == -1) {
1713 ret = KMF_ERR_MEMORY;
1714 goto cleanup;
1715 }
1716
1717 enc_tbs_cert_ptr->Data = (uchar_t *)tbsdata->bv_val;
1718 enc_tbs_cert_ptr->Length = tbsdata->bv_len;
1719
1720 cleanup:
1721 if (ret != KMF_OK)
1722 free_data(enc_tbs_cert_ptr);
1723
1724 if (asn1 != NULL)
1725 kmfber_free(asn1, 1);
1726
1727 if (tbsdata)
1728 free(tbsdata);
1729
1730 return (ret);
1731 }
1732
1733 KMF_RETURN
DerEncodeSignedCertificate(KMF_X509_CERTIFICATE * signed_cert_ptr,KMF_DATA * encodedcert)1734 DerEncodeSignedCertificate(KMF_X509_CERTIFICATE *signed_cert_ptr,
1735 KMF_DATA *encodedcert)
1736 {
1737 KMF_RETURN ret = KMF_OK;
1738 KMF_X509_TBS_CERT *tbscert = NULL;
1739 KMF_X509_SIGNATURE *signature = NULL;
1740 BerElement *asn1 = NULL;
1741 BerValue *tbsdata = NULL;
1742
1743 if (signed_cert_ptr == NULL || encodedcert == NULL)
1744 return (KMF_ERR_BAD_PARAMETER);
1745
1746 encodedcert->Data = NULL;
1747 encodedcert->Length = 0;
1748
1749 tbscert = &signed_cert_ptr->certificate;
1750 signature = &signed_cert_ptr->signature;
1751
1752 asn1 = kmfder_alloc();
1753 if (asn1 == NULL)
1754 return (KMF_ERR_MEMORY);
1755
1756 /* Start outer X509 Certificate SEQUENCE */
1757 if (kmfber_printf(asn1, "{") == -1) {
1758 ret = KMF_ERR_BAD_CERT_FORMAT;
1759 goto cleanup;
1760 }
1761
1762 if ((ret = encode_tbs_cert(asn1, tbscert)) != KMF_OK) {
1763 ret = KMF_ERR_BAD_CERT_FORMAT;
1764 goto cleanup;
1765 }
1766
1767 /* Add the Algorithm & Signature Sequence (no parameters) */
1768 if ((ret = encode_algoid(asn1,
1769 &signature->algorithmIdentifier, FALSE)) != KMF_OK)
1770 goto cleanup;
1771
1772 if (signature->encrypted.Length > 0) {
1773 if (kmfber_printf(asn1, "B", signature->encrypted.Data,
1774 signature->encrypted.Length * 8) == -1) {
1775 ret = KMF_ERR_BAD_CERT_FORMAT;
1776 goto cleanup;
1777 }
1778 }
1779
1780 if (kmfber_printf(asn1, "}") == -1) {
1781 ret = KMF_ERR_BAD_CERT_FORMAT;
1782 goto cleanup;
1783 }
1784
1785 if (kmfber_flatten(asn1, &tbsdata) == -1) {
1786 ret = KMF_ERR_MEMORY;
1787 goto cleanup;
1788 }
1789
1790 encodedcert->Data = (uchar_t *)tbsdata->bv_val;
1791 encodedcert->Length = tbsdata->bv_len;
1792
1793 cleanup:
1794 if (ret != KMF_OK)
1795 free_data(encodedcert);
1796
1797 if (tbsdata)
1798 free(tbsdata);
1799
1800 if (asn1)
1801 kmfber_free(asn1, 1);
1802
1803 return (ret);
1804 }
1805
1806 KMF_RETURN
ExtractX509CertParts(KMF_DATA * x509cert,KMF_DATA * tbscert,KMF_DATA * signature)1807 ExtractX509CertParts(KMF_DATA *x509cert, KMF_DATA *tbscert,
1808 KMF_DATA *signature)
1809 {
1810 KMF_RETURN ret = KMF_OK;
1811 BerElement *der = NULL;
1812 BerValue x509;
1813 ber_tag_t tag;
1814 ber_len_t size;
1815
1816 if (tbscert == NULL || x509cert == NULL)
1817 return (KMF_ERR_BAD_PARAMETER);
1818
1819 x509.bv_val = (char *)x509cert->Data;
1820 x509.bv_len = x509cert->Length;
1821
1822 der = kmfder_init(&x509);
1823 if (der == NULL)
1824 return (KMF_ERR_MEMORY);
1825
1826 /* Skip over the overall Sequence tag to get at the TBS Cert data */
1827 if (kmfber_scanf(der, "Tl", &tag, &size) == -1) {
1828 ret = KMF_ERR_BAD_CERT_FORMAT;
1829 goto cleanup;
1830 }
1831 if (tag != BER_CONSTRUCTED_SEQUENCE) {
1832 ret = KMF_ERR_BAD_CERT_FORMAT;
1833 goto cleanup;
1834 }
1835
1836 /*
1837 * Since we are extracting a copy of the ENCODED bytes, we
1838 * must make sure to also include the bytes for the tag and
1839 * the length fields for the CONSTRUCTED SEQUENCE (TBSCert).
1840 */
1841 size += kmfber_calc_taglen(tag) + kmfber_calc_lenlen(size);
1842
1843 tbscert->Data = malloc(size);
1844 if (tbscert->Data == NULL) {
1845 ret = KMF_ERR_MEMORY;
1846 goto cleanup;
1847 }
1848 tbscert->Length = size;
1849
1850 /* The der data ptr is now set to the start of the TBS cert sequence */
1851 size = kmfber_read(der, (char *)tbscert->Data, tbscert->Length);
1852 if (size != tbscert->Length) {
1853 ret = KMF_ERR_BAD_CERT_FORMAT;
1854 goto cleanup;
1855 }
1856
1857 if (signature != NULL) {
1858 KMF_X509_ALGORITHM_IDENTIFIER algoid;
1859 if ((ret = get_algoid(der, &algoid)) != KMF_OK)
1860 goto cleanup;
1861 free_algoid(&algoid);
1862
1863 if (kmfber_scanf(der, "tl", &tag, &size) != BER_BIT_STRING) {
1864 ret = KMF_ERR_BAD_CERT_FORMAT;
1865 goto cleanup;
1866 }
1867 /* Now get the signature data */
1868 if (kmfber_scanf(der, "B", (char **)&signature->Data,
1869 (ber_len_t *)&signature->Length) == -1) {
1870 ret = KMF_ERR_BAD_CERT_FORMAT;
1871 goto cleanup;
1872 }
1873 /* convert bitstring length to bytes */
1874 signature->Length = signature->Length / 8;
1875 }
1876
1877 cleanup:
1878 if (der)
1879 kmfber_free(der, 1);
1880
1881 if (ret != KMF_OK)
1882 free_data(tbscert);
1883
1884 return (ret);
1885 }
1886
1887 static KMF_RETURN
decode_csr_extensions(BerElement * asn1,KMF_X509_EXTENSIONS * extns)1888 decode_csr_extensions(BerElement *asn1, KMF_X509_EXTENSIONS *extns)
1889 {
1890 KMF_RETURN ret = KMF_OK;
1891 BerValue oid;
1892
1893 if (kmfber_scanf(asn1, "{D", &oid) == -1) {
1894 return (KMF_ERR_UNKNOWN_CSR_ATTRIBUTE);
1895 }
1896
1897 /* We only understand extension requests in a CSR */
1898 if (memcmp(oid.bv_val, extension_request_oid.Data,
1899 oid.bv_len) != 0) {
1900 return (KMF_ERR_UNKNOWN_CSR_ATTRIBUTE);
1901 }
1902
1903 if (kmfber_scanf(asn1, "[") == -1) {
1904 return (KMF_ERR_ENCODING);
1905 }
1906 ret = get_extensions(asn1, extns);
1907
1908
1909 return (ret);
1910 }
1911
1912 static KMF_RETURN
decode_tbscsr_data(BerElement * asn1,KMF_TBS_CSR ** signed_csr_ptr_ptr)1913 decode_tbscsr_data(BerElement *asn1,
1914 KMF_TBS_CSR **signed_csr_ptr_ptr)
1915 {
1916 KMF_RETURN ret = KMF_OK;
1917 KMF_TBS_CSR *tbscsr = NULL;
1918 char *end = NULL;
1919 uint32_t version;
1920 ber_tag_t tag;
1921 ber_len_t size;
1922
1923 /* Now get the version number, it is not optional */
1924 if (kmfber_scanf(asn1, "{i", &version) == -1) {
1925 ret = KMF_ERR_BAD_CERT_FORMAT;
1926 goto cleanup;
1927 }
1928
1929 tbscsr = malloc(sizeof (KMF_TBS_CSR));
1930 if (!tbscsr) {
1931 ret = KMF_ERR_MEMORY;
1932 goto cleanup;
1933 }
1934
1935 (void) memset(tbscsr, 0, sizeof (KMF_TBS_CSR));
1936
1937 if ((ret = set_der_integer(&tbscsr->version, version)) != KMF_OK)
1938 goto cleanup;
1939
1940 if ((ret = get_rdn(asn1, &tbscsr->subject)) != KMF_OK)
1941 goto cleanup;
1942
1943 if ((ret = get_spki(asn1, &tbscsr->subjectPublicKeyInfo)) != KMF_OK)
1944 goto cleanup;
1945
1946 /* Check for the optional fields (attributes) */
1947 if (kmfber_next_element(asn1, &size, end) == 0xA0) {
1948 if (kmfber_scanf(asn1, "Tl", &tag, &size) == -1) {
1949 ret = KMF_ERR_ENCODING;
1950 goto cleanup;
1951 }
1952
1953 ret = decode_csr_extensions(asn1, &tbscsr->extensions);
1954 }
1955 if (ret == KMF_OK)
1956 *signed_csr_ptr_ptr = tbscsr;
1957
1958 cleanup:
1959 if (ret != KMF_OK) {
1960 if (tbscsr) {
1961 free_tbscsr(tbscsr);
1962 free(tbscsr);
1963 }
1964 *signed_csr_ptr_ptr = NULL;
1965 }
1966 return (ret);
1967 }
1968
1969 KMF_RETURN
DerDecodeTbsCsr(const KMF_DATA * Value,KMF_TBS_CSR ** tbscsr)1970 DerDecodeTbsCsr(const KMF_DATA *Value,
1971 KMF_TBS_CSR **tbscsr)
1972 {
1973 KMF_RETURN ret = KMF_OK;
1974 BerElement *asn1 = NULL;
1975 BerValue rawcsr;
1976 KMF_TBS_CSR *newcsr = NULL;
1977
1978 if (!tbscsr || !Value || !Value->Data || !Value->Length)
1979 return (KMF_ERR_BAD_PARAMETER);
1980
1981 rawcsr.bv_val = (char *)Value->Data;
1982 rawcsr.bv_len = Value->Length;
1983
1984 if ((asn1 = kmfder_init(&rawcsr)) == NULL)
1985 return (KMF_ERR_MEMORY);
1986
1987 ret = decode_tbscsr_data(asn1, &newcsr);
1988 if (ret != KMF_OK)
1989 goto cleanup;
1990
1991 *tbscsr = newcsr;
1992
1993 cleanup:
1994 if (ret != KMF_OK) {
1995 if (newcsr)
1996 free_tbscsr(newcsr);
1997 *tbscsr = NULL;
1998 }
1999 kmfber_free(asn1, 1);
2000
2001 return (ret);
2002 }
2003
2004 KMF_RETURN
DerDecodeSignedCsr(const KMF_DATA * Value,KMF_CSR_DATA ** signed_csr_ptr_ptr)2005 DerDecodeSignedCsr(const KMF_DATA *Value,
2006 KMF_CSR_DATA **signed_csr_ptr_ptr)
2007 {
2008 KMF_RETURN ret = KMF_OK;
2009 BerElement *asn1 = NULL;
2010 BerValue rawcsr;
2011 int tag;
2012 ber_len_t size;
2013 char *end = NULL;
2014 char *signature;
2015 KMF_TBS_CSR *tbscsr = NULL;
2016 KMF_CSR_DATA *csrptr = NULL;
2017
2018 if (!signed_csr_ptr_ptr || !Value || !Value->Data || !Value->Length)
2019 return (KMF_ERR_BAD_PARAMETER);
2020
2021 rawcsr.bv_val = (char *)Value->Data;
2022 rawcsr.bv_len = Value->Length;
2023
2024 if ((asn1 = kmfder_init(&rawcsr)) == NULL)
2025 return (KMF_ERR_MEMORY);
2026
2027 if (kmfber_first_element(asn1, &size, &end) !=
2028 BER_CONSTRUCTED_SEQUENCE) {
2029 ret = KMF_ERR_BAD_CERT_FORMAT;
2030 goto cleanup;
2031 }
2032
2033 csrptr = malloc(sizeof (KMF_CSR_DATA));
2034 if (csrptr == NULL) {
2035 ret = KMF_ERR_MEMORY;
2036 goto cleanup;
2037 }
2038 (void) memset(csrptr, 0, sizeof (KMF_CSR_DATA));
2039
2040 ret = decode_tbscsr_data(asn1, &tbscsr);
2041 if (ret != KMF_OK)
2042 goto cleanup;
2043
2044 csrptr->csr = *tbscsr;
2045 free(tbscsr);
2046 tbscsr = NULL;
2047
2048 if ((ret = get_algoid(asn1,
2049 &csrptr->signature.algorithmIdentifier)) != KMF_OK)
2050 goto cleanup;
2051
2052 /* Check to see if the cert has a signature yet */
2053 if (kmfber_next_element(asn1, &size, end) == BER_BIT_STRING) {
2054 /* Finally, get the encrypted signature BITSTRING */
2055 if (kmfber_scanf(asn1, "tl", &tag, &size) == -1) {
2056 ret = KMF_ERR_BAD_CERT_FORMAT;
2057 goto cleanup;
2058 }
2059 if (tag != BER_BIT_STRING) {
2060 ret = KMF_ERR_BAD_CERT_FORMAT;
2061 goto cleanup;
2062 }
2063 if (kmfber_scanf(asn1, "B}", &signature, &size) == -1) {
2064 ret = KMF_ERR_BAD_CERT_FORMAT;
2065 goto cleanup;
2066 }
2067 csrptr->signature.encrypted.Data = (uchar_t *)signature;
2068 csrptr->signature.encrypted.Length = size / 8;
2069 } else {
2070 csrptr->signature.encrypted.Data = NULL;
2071 csrptr->signature.encrypted.Length = 0;
2072 }
2073
2074 *signed_csr_ptr_ptr = csrptr;
2075 cleanup:
2076 if (ret != KMF_OK) {
2077 free_tbscsr(&csrptr->csr);
2078 free_algoid(&csrptr->signature.algorithmIdentifier);
2079 if (csrptr->signature.encrypted.Data)
2080 free(csrptr->signature.encrypted.Data);
2081
2082 if (csrptr)
2083 free(csrptr);
2084
2085 *signed_csr_ptr_ptr = NULL;
2086 }
2087 if (asn1)
2088 kmfber_free(asn1, 1);
2089
2090 return (ret);
2091
2092 }
2093
2094 static KMF_RETURN
encode_csr_extensions(BerElement * asn1,KMF_TBS_CSR * tbscsr)2095 encode_csr_extensions(BerElement *asn1, KMF_TBS_CSR *tbscsr)
2096 {
2097 KMF_RETURN ret = KMF_OK;
2098 int attlen = 0;
2099 BerElement *extnasn1 = NULL;
2100 BerValue *extnvalue = NULL;
2101
2102 /* Optional field: CSR attributes and extensions */
2103 if (tbscsr->extensions.numberOfExtensions > 0) {
2104 if (kmfber_printf(asn1, "T", 0xA0) == -1) {
2105 ret = KMF_ERR_ENCODING;
2106 goto cleanup;
2107 }
2108 } else {
2109 /* No extensions or attributes to encode */
2110 return (KMF_OK);
2111 }
2112
2113 /*
2114 * attributes [0] Attributes
2115 * Attributes := SET OF Attribute
2116 * Attribute := SEQUENCE {
2117 * { ATTRIBUTE ID
2118 * values SET SIZE(1..MAX) of ATTRIBUTE
2119 * }
2120 *
2121 * Ex: { ExtensionRequest OID [ { {extn1 } , {extn2 } } ] }
2122 */
2123
2124 /*
2125 * Encode any extensions and add to the attributes section.
2126 */
2127 if (tbscsr->extensions.numberOfExtensions > 0) {
2128 extnasn1 = kmfder_alloc();
2129 if (extnasn1 == NULL) {
2130 ret = KMF_ERR_MEMORY;
2131 goto cleanup;
2132 }
2133
2134 if (kmfber_printf(extnasn1, "{D[{",
2135 &extension_request_oid) == -1) {
2136 ret = KMF_ERR_ENCODING;
2137 goto cleanup_1;
2138 }
2139
2140 if ((ret = encode_extension_list(extnasn1,
2141 &tbscsr->extensions)) != KMF_OK) {
2142 goto cleanup_1;
2143 }
2144
2145 if (kmfber_printf(extnasn1, "}]}") == -1) {
2146 ret = KMF_ERR_ENCODING;
2147 goto cleanup_1;
2148 }
2149
2150 if (kmfber_flatten(extnasn1, &extnvalue) == -1) {
2151 ret = KMF_ERR_MEMORY;
2152 goto cleanup_1;
2153 }
2154 cleanup_1:
2155 kmfber_free(extnasn1, 1);
2156
2157 if (ret == KMF_OK)
2158 /* Add 2 bytes to cover the tag and the length */
2159 attlen = extnvalue->bv_len;
2160 }
2161 if (ret != KMF_OK)
2162 goto cleanup;
2163
2164 if (kmfber_printf(asn1, "l", attlen) == -1) {
2165 ret = KMF_ERR_ENCODING;
2166 goto cleanup;
2167 }
2168
2169 /* Write the actual encoded extensions */
2170 if (extnvalue != NULL && extnvalue->bv_val != NULL) {
2171 if (kmfber_write(asn1, extnvalue->bv_val,
2172 extnvalue->bv_len, 0) == -1) {
2173 ret = KMF_ERR_ENCODING;
2174 goto cleanup;
2175 }
2176 }
2177
2178 cleanup:
2179 /*
2180 * Memory cleanup is done in the caller or in the individual
2181 * encoding routines.
2182 */
2183 if (extnvalue) {
2184 if (extnvalue->bv_val)
2185 free(extnvalue->bv_val);
2186 free(extnvalue);
2187 }
2188
2189 return (ret);
2190 }
2191
2192 static KMF_RETURN
encode_tbs_csr(BerElement * asn1,KMF_TBS_CSR * tbscsr)2193 encode_tbs_csr(BerElement *asn1, KMF_TBS_CSR *tbscsr)
2194 {
2195 KMF_RETURN ret = KMF_OK;
2196 uint32_t version;
2197
2198 /* Start the version */
2199 (void) memcpy(&version, tbscsr->version.Data,
2200 tbscsr->version.Length);
2201
2202 if (kmfber_printf(asn1, "{i", version) == -1) {
2203 ret = KMF_ERR_BAD_CERT_FORMAT;
2204 goto cleanup;
2205 }
2206
2207 /* Encode the Subject RDN */
2208 if ((ret = encode_rdn(asn1, &tbscsr->subject)) != KMF_OK)
2209 goto cleanup;
2210
2211 /* Encode the Subject Public Key Info */
2212 if ((ret = encode_spki(asn1, &tbscsr->subjectPublicKeyInfo)) != KMF_OK)
2213 goto cleanup;
2214
2215 if ((ret = encode_csr_extensions(asn1, tbscsr)) != KMF_OK)
2216 goto cleanup;
2217
2218 /* Close out the TBSCert sequence */
2219 if (kmfber_printf(asn1, "}") == -1) {
2220 ret = KMF_ERR_BAD_CERT_FORMAT;
2221 goto cleanup;
2222 }
2223
2224 cleanup:
2225 return (ret);
2226 }
2227
2228 KMF_RETURN
DerEncodeDSAPrivateKey(KMF_DATA * encodedkey,KMF_RAW_DSA_KEY * dsa)2229 DerEncodeDSAPrivateKey(KMF_DATA *encodedkey, KMF_RAW_DSA_KEY *dsa)
2230 {
2231 KMF_RETURN rv = KMF_OK;
2232 BerElement *asn1 = NULL;
2233 BerValue *dsadata = NULL;
2234
2235 asn1 = kmfder_alloc();
2236 if (asn1 == NULL)
2237 return (KMF_ERR_MEMORY);
2238
2239 if (kmfber_printf(asn1, "I",
2240 dsa->value.val, dsa->value.len) == -1) {
2241 rv = KMF_ERR_MEMORY;
2242 goto cleanup;
2243 }
2244
2245 if (kmfber_flatten(asn1, &dsadata) == -1) {
2246 rv = KMF_ERR_MEMORY;
2247 goto cleanup;
2248 }
2249
2250 encodedkey->Data = (uchar_t *)dsadata->bv_val;
2251 encodedkey->Length = dsadata->bv_len;
2252
2253 free(dsadata);
2254 cleanup:
2255 kmfber_free(asn1, 1);
2256 return (rv);
2257 }
2258
2259 KMF_RETURN
DerEncodeRSAPrivateKey(KMF_DATA * encodedkey,KMF_RAW_RSA_KEY * rsa)2260 DerEncodeRSAPrivateKey(KMF_DATA *encodedkey, KMF_RAW_RSA_KEY *rsa)
2261 {
2262 KMF_RETURN rv = KMF_OK;
2263 BerElement *asn1 = NULL;
2264 uchar_t ver = 0;
2265 BerValue *rsadata = NULL;
2266
2267 asn1 = kmfder_alloc();
2268 if (asn1 == NULL)
2269 return (KMF_ERR_MEMORY);
2270
2271 if (kmfber_printf(asn1, "{IIIIIIIII}",
2272 &ver, 1,
2273 rsa->mod.val, rsa->mod.len,
2274 rsa->pubexp.val, rsa->pubexp.len,
2275 rsa->priexp.val, rsa->priexp.len,
2276 rsa->prime1.val, rsa->prime1.len,
2277 rsa->prime2.val, rsa->prime2.len,
2278 rsa->exp1.val, rsa->exp1.len,
2279 rsa->exp2.val, rsa->exp2.len,
2280 rsa->coef.val, rsa->coef.len) == -1)
2281 goto cleanup;
2282
2283 if (kmfber_flatten(asn1, &rsadata) == -1) {
2284 rv = KMF_ERR_MEMORY;
2285 goto cleanup;
2286 }
2287
2288 encodedkey->Data = (uchar_t *)rsadata->bv_val;
2289 encodedkey->Length = rsadata->bv_len;
2290
2291 free(rsadata);
2292 cleanup:
2293 kmfber_free(asn1, 1);
2294 return (rv);
2295 }
2296
2297 KMF_RETURN
DerEncodeECPrivateKey(KMF_DATA * encodedkey,KMF_RAW_EC_KEY * eckey)2298 DerEncodeECPrivateKey(KMF_DATA *encodedkey, KMF_RAW_EC_KEY *eckey)
2299 {
2300 KMF_RETURN rv = KMF_OK;
2301 BerElement *asn1 = NULL;
2302 uchar_t ver = 1;
2303 BerValue *data = NULL;
2304
2305 asn1 = kmfder_alloc();
2306 if (asn1 == NULL)
2307 return (KMF_ERR_MEMORY);
2308
2309 if (kmfber_printf(asn1, "{io",
2310 ver, eckey->value.val, eckey->value.len) == -1) {
2311 rv = KMF_ERR_ENCODING;
2312 goto cleanup;
2313 }
2314 /*
2315 * Indicate that we are using the named curve option
2316 * for the parameters.
2317 */
2318 if (kmfber_printf(asn1, "T", 0xA0) == -1) {
2319 rv = KMF_ERR_ENCODING;
2320 goto cleanup;
2321 }
2322 if (kmfber_printf(asn1, "l", eckey->params.Length) == -1) {
2323 rv = KMF_ERR_ENCODING;
2324 goto cleanup;
2325 }
2326 if (kmfber_write(asn1, (char *)eckey->params.Data,
2327 eckey->params.Length, 0) == -1) {
2328 rv = KMF_ERR_ENCODING;
2329 goto cleanup;
2330 }
2331 if (kmfber_printf(asn1, "}") == -1) {
2332 rv = KMF_ERR_ENCODING;
2333 goto cleanup;
2334 }
2335 if (kmfber_flatten(asn1, &data) == -1) {
2336 rv = KMF_ERR_MEMORY;
2337 goto cleanup;
2338 }
2339 encodedkey->Data = (uchar_t *)data->bv_val;
2340 encodedkey->Length = data->bv_len;
2341
2342 cleanup:
2343 kmfber_free(asn1, 1);
2344 return (rv);
2345 }
2346
2347
2348 KMF_RETURN
DerEncodeTbsCsr(KMF_TBS_CSR * tbs_csr_ptr,KMF_DATA * enc_tbs_csr_ptr)2349 DerEncodeTbsCsr(KMF_TBS_CSR *tbs_csr_ptr,
2350 KMF_DATA *enc_tbs_csr_ptr)
2351 {
2352 KMF_RETURN ret;
2353 BerValue *tbsdata = NULL;
2354 BerElement *asn1 = NULL;
2355
2356 asn1 = kmfder_alloc();
2357
2358 enc_tbs_csr_ptr->Data = NULL;
2359 enc_tbs_csr_ptr->Length = 0;
2360
2361 if (asn1 == NULL)
2362 return (KMF_ERR_MEMORY);
2363
2364 ret = encode_tbs_csr(asn1, tbs_csr_ptr);
2365 if (ret != KMF_OK)
2366 goto cleanup;
2367
2368 if (kmfber_flatten(asn1, &tbsdata) == -1) {
2369 ret = KMF_ERR_MEMORY;
2370 goto cleanup;
2371 }
2372
2373 enc_tbs_csr_ptr->Data = (uchar_t *)tbsdata->bv_val;
2374 enc_tbs_csr_ptr->Length = tbsdata->bv_len;
2375
2376 cleanup:
2377 if (ret != KMF_OK)
2378 free_data(enc_tbs_csr_ptr);
2379
2380 if (asn1 != NULL)
2381 kmfber_free(asn1, 1);
2382
2383 if (tbsdata)
2384 free(tbsdata);
2385
2386 return (ret);
2387 }
2388
2389 KMF_RETURN
DerEncodeSignedCsr(KMF_CSR_DATA * signed_csr_ptr,KMF_DATA * encodedcsr)2390 DerEncodeSignedCsr(KMF_CSR_DATA *signed_csr_ptr,
2391 KMF_DATA *encodedcsr)
2392 {
2393 KMF_RETURN ret = KMF_OK;
2394 KMF_TBS_CSR *tbscsr = NULL;
2395 KMF_X509_SIGNATURE *signature = NULL;
2396 BerElement *asn1 = NULL;
2397 BerValue *tbsdata = NULL;
2398
2399 if (signed_csr_ptr == NULL)
2400 return (KMF_ERR_BAD_PARAMETER);
2401
2402 tbscsr = &signed_csr_ptr->csr;
2403 signature = &signed_csr_ptr->signature;
2404
2405 asn1 = kmfder_alloc();
2406 if (asn1 == NULL)
2407 return (KMF_ERR_MEMORY);
2408
2409 /* Start outer CSR SEQUENCE */
2410 if (kmfber_printf(asn1, "{") == -1) {
2411 ret = KMF_ERR_BAD_CERT_FORMAT;
2412 goto cleanup;
2413 }
2414
2415 ret = encode_tbs_csr(asn1, tbscsr);
2416
2417 /* Add the Algorithm & Signature Sequence */
2418 if ((ret = encode_algoid(asn1,
2419 &signature->algorithmIdentifier, FALSE)) != KMF_OK)
2420 goto cleanup;
2421
2422 if (signature->encrypted.Length > 0) {
2423 if (kmfber_printf(asn1, "B", signature->encrypted.Data,
2424 signature->encrypted.Length * 8) == -1) {
2425 ret = KMF_ERR_BAD_CERT_FORMAT;
2426 goto cleanup;
2427 }
2428 }
2429
2430 if (kmfber_printf(asn1, "}") == -1) {
2431 ret = KMF_ERR_BAD_CERT_FORMAT;
2432 goto cleanup;
2433 }
2434
2435 if (kmfber_flatten(asn1, &tbsdata) == -1) {
2436 ret = KMF_ERR_MEMORY;
2437 goto cleanup;
2438 }
2439
2440 encodedcsr->Data = (uchar_t *)tbsdata->bv_val;
2441 encodedcsr->Length = tbsdata->bv_len;
2442
2443 cleanup:
2444 if (ret != KMF_OK) {
2445 free_data(encodedcsr);
2446 }
2447
2448 if (tbsdata)
2449 free(tbsdata);
2450
2451 if (asn1)
2452 kmfber_free(asn1, 1);
2453 return (ret);
2454 }
2455
2456 static KMF_RETURN
ber_copy_data(KMF_DATA * dst,KMF_DATA * src)2457 ber_copy_data(KMF_DATA *dst, KMF_DATA *src)
2458 {
2459 KMF_RETURN ret = KMF_OK;
2460
2461 if (dst == NULL || src == NULL)
2462 return (KMF_ERR_BAD_PARAMETER);
2463
2464 dst->Data = malloc(src->Length);
2465 if (dst->Data == NULL)
2466 return (KMF_ERR_MEMORY);
2467
2468 dst->Length = src->Length;
2469 (void) memcpy(dst->Data, src->Data, src->Length);
2470
2471 return (ret);
2472 }
2473
2474 KMF_RETURN
ExtractSPKIData(const KMF_X509_SPKI * pKey,KMF_ALGORITHM_INDEX AlgorithmId,KMF_DATA * pKeyParts,uint32_t * uNumKeyParts)2475 ExtractSPKIData(
2476 const KMF_X509_SPKI *pKey,
2477 KMF_ALGORITHM_INDEX AlgorithmId,
2478 KMF_DATA *pKeyParts,
2479 uint32_t *uNumKeyParts)
2480 {
2481 KMF_RETURN ret = KMF_OK;
2482 BerElement *asn1 = NULL;
2483 BerValue *P, *Q, *G, *Mod, *Exp, *PubKey;
2484 BerValue PubKeyParams, PubKeyData;
2485
2486 if (pKeyParts == NULL || uNumKeyParts == NULL || pKey == NULL)
2487 return (KMF_ERR_BAD_PARAMETER);
2488
2489 switch (AlgorithmId) {
2490 case KMF_ALGID_DSA:
2491 case KMF_ALGID_SHA1WithDSA:
2492 *uNumKeyParts = 0;
2493 /* Get the parameters from the algorithm definition */
2494 PubKeyParams.bv_val =
2495 (char *)pKey->algorithm.parameters.Data;
2496 PubKeyParams.bv_len = pKey->algorithm.parameters.Length;
2497 if ((asn1 = kmfder_init(&PubKeyParams)) == NULL)
2498 return (KMF_ERR_MEMORY);
2499
2500 if (kmfber_scanf(asn1, "{III}", &P, &Q, &G) == -1) {
2501 kmfber_free(asn1, 1);
2502 return (KMF_ERR_BAD_KEY_FORMAT);
2503 }
2504 pKeyParts[KMF_DSA_PRIME].Data = (uchar_t *)P->bv_val;
2505 pKeyParts[KMF_DSA_PRIME].Length = P->bv_len;
2506 pKeyParts[KMF_DSA_SUB_PRIME].Data =
2507 (uchar_t *)Q->bv_val;
2508 pKeyParts[KMF_DSA_SUB_PRIME].Length = Q->bv_len;
2509 pKeyParts[KMF_DSA_BASE].Data = (uchar_t *)G->bv_val;
2510 pKeyParts[KMF_DSA_BASE].Length = G->bv_len;
2511
2512 free(P);
2513 free(Q);
2514 free(G);
2515 kmfber_free(asn1, 1);
2516
2517 /* Get the PubKey data */
2518 PubKeyData.bv_val = (char *)pKey->subjectPublicKey.Data;
2519 PubKeyData.bv_len = pKey->subjectPublicKey.Length;
2520 if ((asn1 = kmfder_init(&PubKeyData)) == NULL) {
2521 ret = KMF_ERR_MEMORY;
2522 goto cleanup;
2523 }
2524 PubKey = NULL;
2525 if (kmfber_scanf(asn1, "I", &PubKey) == -1) {
2526 ret = KMF_ERR_BAD_KEY_FORMAT;
2527 goto cleanup;
2528 }
2529 pKeyParts[KMF_DSA_PUBLIC_VALUE].Data =
2530 (uchar_t *)PubKey->bv_val;
2531 pKeyParts[KMF_DSA_PUBLIC_VALUE].Length = PubKey->bv_len;
2532
2533 free(PubKey);
2534
2535 *uNumKeyParts = KMF_NUMBER_DSA_PUBLIC_KEY_PARTS;
2536 break;
2537 case KMF_ALGID_SHA1WithECDSA:
2538 case KMF_ALGID_ECDSA:
2539 (void) ber_copy_data(&pKeyParts[KMF_ECDSA_PARAMS],
2540 (KMF_DATA *)&pKey->algorithm.parameters);
2541
2542 (void) ber_copy_data(&pKeyParts[KMF_ECDSA_POINT],
2543 (KMF_DATA *)&pKey->subjectPublicKey);
2544
2545 *uNumKeyParts = 2;
2546 break;
2547
2548 case KMF_ALGID_RSA:
2549 case KMF_ALGID_MD2WithRSA:
2550 case KMF_ALGID_MD5WithRSA:
2551 case KMF_ALGID_SHA1WithRSA:
2552 *uNumKeyParts = 0;
2553 PubKeyData.bv_val = (char *)pKey->subjectPublicKey.Data;
2554 PubKeyData.bv_len = pKey->subjectPublicKey.Length;
2555 if ((asn1 = kmfder_init(&PubKeyData)) == NULL) {
2556 ret = KMF_ERR_MEMORY;
2557 goto cleanup;
2558 }
2559 if (kmfber_scanf(asn1, "{II}", &Mod, &Exp) == -1) {
2560 ret = KMF_ERR_BAD_KEY_FORMAT;
2561 goto cleanup;
2562 }
2563 pKeyParts[KMF_RSA_MODULUS].Data =
2564 (uchar_t *)Mod->bv_val;
2565 pKeyParts[KMF_RSA_MODULUS].Length = Mod->bv_len;
2566 pKeyParts[KMF_RSA_PUBLIC_EXPONENT].Data =
2567 (uchar_t *)Exp->bv_val;
2568 pKeyParts[KMF_RSA_PUBLIC_EXPONENT].Length = Exp->bv_len;
2569 *uNumKeyParts = KMF_NUMBER_RSA_PUBLIC_KEY_PARTS;
2570
2571 free(Mod);
2572 free(Exp);
2573 break;
2574 default:
2575 return (KMF_ERR_BAD_PARAMETER);
2576 }
2577 cleanup:
2578 if (ret != KMF_OK) {
2579 int i;
2580 for (i = 0; i < *uNumKeyParts; i++)
2581 free_data(&pKeyParts[i]);
2582 }
2583 if (asn1 != NULL) {
2584 kmfber_free(asn1, 1);
2585 }
2586
2587 return (ret);
2588 }
2589