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 cleanup:
624 if (ret != KMF_OK) {
625 free_decoded_spki(spki);
626 }
627 kmfber_free(asn1, 1);
628
629 return (ret);
630 }
631
632 KMF_RETURN
CopySPKI(KMF_X509_SPKI * src,KMF_X509_SPKI ** dest)633 CopySPKI(KMF_X509_SPKI *src,
634 KMF_X509_SPKI **dest)
635 {
636 KMF_RETURN ret = KMF_OK;
637 KMF_X509_SPKI *newspki;
638
639 *dest = NULL;
640
641 newspki = malloc(sizeof (KMF_X509_SPKI));
642 if (newspki == NULL)
643 return (KMF_ERR_MEMORY);
644 (void) memset(newspki, 0, sizeof (KMF_X509_SPKI));
645
646 ret = CopyData(&src->algorithm.algorithm,
647 &newspki->algorithm.algorithm);
648 if (ret != KMF_OK)
649 goto cleanup;
650
651 ret = CopyData(&src->algorithm.parameters,
652 &newspki->algorithm.parameters);
653 if (ret != KMF_OK)
654 goto cleanup;
655
656 ret = CopyData(&src->subjectPublicKey,
657 &newspki->subjectPublicKey);
658 if (ret != KMF_OK)
659 goto cleanup;
660
661 *dest = newspki;
662 cleanup:
663 if (ret != KMF_OK) {
664 if (newspki)
665 free_decoded_spki(newspki);
666 }
667 return (ret);
668 }
669
670 static KMF_RETURN
encode_validity(BerElement * asn1,KMF_X509_VALIDITY * validity)671 encode_validity(BerElement *asn1, KMF_X509_VALIDITY *validity)
672 {
673 int ret;
674
675 ret = kmfber_printf(asn1, "{tsts}",
676 validity->notBefore.timeType,
677 validity->notBefore.time.Data,
678 validity->notAfter.timeType,
679 validity->notAfter.time.Data);
680
681 if (ret == -1)
682 return (KMF_ERR_BAD_CERT_FORMAT);
683
684 return (KMF_OK);
685 }
686
687 static KMF_RETURN
get_validity(BerElement * asn1,KMF_X509_VALIDITY * validity)688 get_validity(BerElement *asn1, KMF_X509_VALIDITY *validity)
689 {
690 KMF_RETURN ret = KMF_OK;
691 int tag;
692 int t1, t2;
693 ber_len_t size;
694 char *t1str, *t2str;
695
696 (void) memset(validity, 0, sizeof (KMF_X509_VALIDITY));
697
698 tag = kmfber_next_element(asn1, &size, NULL);
699 if (tag != BER_CONSTRUCTED_SEQUENCE) {
700 return (KMF_ERR_BAD_CERT_FORMAT);
701 }
702
703 if (kmfber_scanf(asn1, "{tata}", &t1, &t1str, &t2, &t2str) == -1) {
704 return (KMF_ERR_BAD_CERT_FORMAT);
705 }
706
707 validity->notBefore.timeType = t1;
708 validity->notBefore.time.Data = (uchar_t *)t1str;
709 validity->notBefore.time.Length = strlen(t1str);
710
711 validity->notAfter.timeType = t2;
712 validity->notAfter.time.Data = (uchar_t *)t2str;
713 validity->notAfter.time.Length = strlen(t2str);
714
715 return (ret);
716 }
717
718 KMF_RETURN
AddRDN(KMF_X509_NAME * name,KMF_X509_RDN * newrdn)719 AddRDN(KMF_X509_NAME *name, KMF_X509_RDN *newrdn)
720 {
721 KMF_RETURN ret = KMF_OK;
722 KMF_X509_RDN *rdnslot = NULL;
723
724 /* Add new RDN record to existing list */
725 name->numberOfRDNs++;
726 name->RelativeDistinguishedName =
727 realloc(name->RelativeDistinguishedName,
728 name->numberOfRDNs * sizeof (KMF_X509_RDN));
729
730 if (name->RelativeDistinguishedName == NULL) {
731 ret = KMF_ERR_MEMORY;
732 goto cleanup;
733 }
734 rdnslot = &name->RelativeDistinguishedName[name->numberOfRDNs-1];
735
736 if (newrdn) {
737 (void) memcpy(rdnslot, newrdn, sizeof (KMF_X509_RDN));
738 } else {
739 rdnslot->numberOfPairs = 0;
740 rdnslot->AttributeTypeAndValue = NULL;
741 }
742
743 cleanup:
744 /* No cleanup needed here */
745 return (ret);
746 }
747
748 static KMF_RETURN
encode_rdn(BerElement * asn1,KMF_X509_NAME * name)749 encode_rdn(BerElement *asn1, KMF_X509_NAME *name)
750 {
751 KMF_RETURN ret = KMF_OK;
752 KMF_X509_TYPE_VALUE_PAIR *attrtvpair = NULL;
753 int i;
754 KMF_X509_RDN *rdn;
755
756 if (kmfber_printf(asn1, "{") == -1) {
757 ret = KMF_ERR_MEMORY;
758 goto cleanup;
759 }
760
761 for (i = 0; i < name->numberOfRDNs; i++) {
762 if (kmfber_printf(asn1, "[") == -1) {
763 ret = KMF_ERR_MEMORY;
764 goto cleanup;
765 }
766 rdn = &name->RelativeDistinguishedName[i];
767 attrtvpair = rdn->AttributeTypeAndValue;
768
769 if (rdn->numberOfPairs > 0) {
770 if (kmfber_printf(asn1, "{Dto}",
771 &attrtvpair->type,
772 attrtvpair->valueType,
773 attrtvpair->value.Data,
774 attrtvpair->value.Length) == -1) {
775 ret = KMF_ERR_MEMORY;
776 goto cleanup;
777 }
778 }
779 if (kmfber_printf(asn1, "]") == -1) {
780 ret = KMF_ERR_MEMORY;
781 goto cleanup;
782 }
783 }
784
785 if (kmfber_printf(asn1, "}") == -1) {
786 ret = KMF_ERR_MEMORY;
787 goto cleanup;
788 }
789
790 cleanup:
791 /* No cleanup needed here */
792
793 return (ret);
794 }
795
796
797 KMF_RETURN
CopyRDN(KMF_X509_NAME * srcname,KMF_X509_NAME ** destname)798 CopyRDN(KMF_X509_NAME *srcname, KMF_X509_NAME **destname)
799 {
800 KMF_RETURN ret = KMF_OK;
801 KMF_X509_NAME *newname = NULL;
802 KMF_X509_RDN *rdn, *dstrdn;
803 KMF_X509_TYPE_VALUE_PAIR *av = NULL;
804 KMF_X509_TYPE_VALUE_PAIR *srcav = NULL;
805 KMF_X509_TYPE_VALUE_PAIR *dstav = NULL;
806 int i, j;
807
808 newname = malloc(sizeof (KMF_X509_NAME));
809 if (newname == NULL)
810 return (KMF_ERR_MEMORY);
811 (void) memset(newname, 0, sizeof (KMF_X509_NAME));
812
813 newname->numberOfRDNs = srcname->numberOfRDNs;
814 newname->RelativeDistinguishedName = malloc(newname->numberOfRDNs *
815 sizeof (KMF_X509_RDN));
816 if (newname->RelativeDistinguishedName == NULL) {
817 free(newname);
818 return (KMF_ERR_MEMORY);
819 }
820 /* Copy each RDN in the list */
821 for (i = 0; i < newname->numberOfRDNs; i++) {
822 rdn = &srcname->RelativeDistinguishedName[i];
823
824 dstrdn = &newname->RelativeDistinguishedName[i];
825 (void) memset(dstrdn, 0, sizeof (KMF_X509_RDN));
826
827 dstrdn->numberOfPairs = rdn->numberOfPairs;
828 if (dstrdn->numberOfPairs > 0) {
829 av = malloc(dstrdn->numberOfPairs *
830 sizeof (KMF_X509_TYPE_VALUE_PAIR));
831 if (av == NULL) {
832 ret = KMF_ERR_MEMORY;
833 goto cleanup;
834 }
835 (void) memset(av, 0, dstrdn->numberOfPairs *
836 sizeof (KMF_X509_TYPE_VALUE_PAIR));
837
838 dstrdn->AttributeTypeAndValue = av;
839 if (av == NULL) {
840 ret = KMF_ERR_MEMORY;
841 goto cleanup;
842 }
843 /* Copy each A/V pair in the list */
844 for (j = 0; j < dstrdn->numberOfPairs; j++) {
845 srcav = &rdn->AttributeTypeAndValue[j];
846 dstav = &dstrdn->AttributeTypeAndValue[j];
847 if ((ret = CopyData(&srcav->type,
848 &dstav->type)) != KMF_OK)
849 goto cleanup;
850 dstav->valueType = srcav->valueType;
851 if ((ret = CopyData(&srcav->value,
852 &dstav->value)) != KMF_OK)
853 goto cleanup;
854 }
855 } else {
856 dstrdn->AttributeTypeAndValue = NULL;
857 }
858 }
859 *destname = newname;
860
861 cleanup:
862 if (ret != KMF_OK) {
863 if (newname)
864 free_rdn_data(newname);
865
866 free(newname);
867 *destname = NULL;
868 }
869 return (ret);
870 }
871
872 #define VALID_DIRECTORYSTRING_TAG(t) ( \
873 (t == BER_UTF8_STRING) || \
874 (t == BER_PRINTABLE_STRING) || \
875 (t == BER_IA5STRING) || \
876 (t == BER_T61STRING) || \
877 (t == BER_BMP_STRING) || \
878 (t == BER_UNIVERSAL_STRING))
879
880 static KMF_RETURN
get_rdn(BerElement * asn1,KMF_X509_NAME * name)881 get_rdn(BerElement *asn1, KMF_X509_NAME *name)
882 {
883 KMF_RETURN ret = KMF_OK;
884 ber_len_t size;
885 char *end;
886 int tag;
887 BerValue AttrOID;
888 char *AttrValue = NULL;
889 KMF_X509_TYPE_VALUE_PAIR *newpair = NULL;
890 KMF_X509_RDN newrdn;
891
892 /*
893 * AttributeType ::= OBJECT IDENTIFIER
894 * AttributeValue ::= ANY
895 *
896 * AttributeTypeAndValue ::= SEQUENCE {
897 * type AttributeType,
898 * value AttributeValue }
899 *
900 * Name ::= CHOICE { -- only one possibility for now --
901 * rdnSequence RDNSequence }
902 *
903 * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
904 *
905 * DistinguishedName ::= RDNSequence
906 *
907 * RelativeDistinguishedName ::=
908 * SET SIZE (1 .. MAX) OF AttributeTypeAndValue
909 *
910 */
911
912 name->numberOfRDNs = 0;
913 name->RelativeDistinguishedName = NULL;
914
915 /* Get the beginning of the RDN Set and a ptr to the end */
916 tag = kmfber_first_element(asn1, &size, &end);
917 if (tag != BER_CONSTRUCTED_SET) {
918 goto cleanup;
919 }
920
921 /* Walk through the individual SET items until the "end" is reached */
922 while ((tag = kmfber_next_element(asn1, &size, end)) ==
923 BER_CONSTRUCTED_SET) {
924 /* Skip over the SET tag */
925 if (kmfber_scanf(asn1, "T", &tag) == -1) {
926 ret = KMF_ERR_BAD_CERT_FORMAT;
927 break;
928 }
929
930 /* An "empty" set member means we tack on an empty node */
931 if (size == 0) {
932 if ((ret = AddRDN(name, NULL)) != KMF_OK)
933 goto cleanup;
934 continue;
935 }
936
937 /* Attr OID and peek at the next tag and field length */
938 if (kmfber_scanf(asn1, "{Dtl", &AttrOID, &tag, &size) == -1) {
939 ret = KMF_ERR_BAD_CERT_FORMAT;
940 break;
941 }
942
943 if (!(VALID_DIRECTORYSTRING_TAG(tag))) {
944 ret = KMF_ERR_BAD_CERT_FORMAT;
945 break;
946 }
947
948 if (kmfber_scanf(asn1, "a}]", &AttrValue) == -1) {
949 ret = KMF_ERR_BAD_CERT_FORMAT;
950 break;
951 }
952
953 /* Allocate a new name/value pair record */
954 newpair = malloc(sizeof (KMF_X509_TYPE_VALUE_PAIR));
955 if (newpair == NULL) {
956 ret = KMF_ERR_MEMORY;
957 break;
958 }
959 (void) memset(newpair, 0, sizeof (KMF_X509_TYPE_VALUE_PAIR));
960 newpair->type.Data = (uchar_t *)AttrOID.bv_val;
961 newpair->type.Length = AttrOID.bv_len;
962 newpair->valueType = tag; /* what kind of string is it? */
963 newpair->value.Data = (uchar_t *)AttrValue;
964 newpair->value.Length = strlen(AttrValue);
965
966 (void) memset(&newrdn, 0, sizeof (KMF_X509_RDN));
967 newrdn.numberOfPairs = 1;
968 newrdn.AttributeTypeAndValue = newpair;
969
970 if ((ret = AddRDN(name, &newrdn)) != KMF_OK)
971 break;
972 }
973
974 cleanup:
975 if (ret != KMF_OK) {
976 free_rdn_data(name);
977 }
978 return (ret);
979 }
980
981 static KMF_RETURN
set_der_integer(KMF_DATA * data,int value)982 set_der_integer(KMF_DATA *data, int value)
983 {
984 if (data == NULL)
985 return (KMF_ERR_BAD_PARAMETER);
986
987 data->Data = malloc(sizeof (int));
988 if (data->Data == NULL)
989 return (KMF_ERR_MEMORY);
990
991 data->Length = sizeof (int);
992 (void) memcpy((void *)data->Data, (const void *)&value, sizeof (int));
993
994 return (KMF_OK);
995 }
996
997 static KMF_RETURN
set_bigint(KMF_BIGINT * data,KMF_BIGINT * bigint)998 set_bigint(KMF_BIGINT *data, KMF_BIGINT *bigint)
999 {
1000 if (data == NULL || bigint == NULL)
1001 return (KMF_ERR_BAD_PARAMETER);
1002
1003 data->val = malloc(bigint->len);
1004 if (data->val == NULL)
1005 return (KMF_ERR_MEMORY);
1006
1007 data->len = bigint->len;
1008 (void) memcpy((void *)data->val, (const void *)bigint->val,
1009 bigint->len);
1010
1011 return (KMF_OK);
1012 }
1013
1014 static KMF_RETURN
encode_uniqueid(BerElement * asn1,int tag,KMF_DATA * id)1015 encode_uniqueid(BerElement *asn1, int tag, KMF_DATA *id)
1016 {
1017 KMF_RETURN ret = KMF_OK;
1018 uint32_t len;
1019
1020 len = kmfber_calc_taglen(BER_BIT_STRING) +
1021 kmfber_calc_lenlen(id->Length * 8) + id->Length;
1022 if (kmfber_printf(asn1, "TlB", tag, len,
1023 id->Data, id->Length * 8) == -1)
1024 return (KMF_ERR_BAD_CERT_FORMAT);
1025
1026 return (ret);
1027 }
1028
1029 static KMF_RETURN
encode_extension_list(BerElement * asn1,KMF_X509_EXTENSIONS * extns)1030 encode_extension_list(BerElement *asn1, KMF_X509_EXTENSIONS *extns)
1031 {
1032 KMF_RETURN ret = KMF_OK;
1033 int i;
1034
1035 for (i = 0; i < extns->numberOfExtensions; i++) {
1036 BerValue v;
1037 v.bv_val = (char *)extns->extensions[i].extnId.Data;
1038 v.bv_len = extns->extensions[i].extnId.Length;
1039
1040 if (kmfber_printf(asn1, "{D", &v) == -1) {
1041 ret = KMF_ERR_ENCODING;
1042 goto cleanup;
1043 }
1044
1045 if (extns->extensions[i].critical) {
1046 if (kmfber_printf(asn1, "b",
1047 extns->extensions[i].critical) == -1) {
1048 ret = KMF_ERR_ENCODING;
1049 goto cleanup;
1050 }
1051 }
1052
1053 if (kmfber_printf(asn1, "o}",
1054 extns->extensions[i].BERvalue.Data,
1055 extns->extensions[i].BERvalue.Length) == -1) {
1056 ret = KMF_ERR_ENCODING;
1057 goto cleanup;
1058 }
1059 }
1060 cleanup:
1061 return (ret);
1062 }
1063
1064 static KMF_RETURN
encode_extensions(BerElement * asn1,KMF_X509_EXTENSIONS * extns)1065 encode_extensions(BerElement *asn1, KMF_X509_EXTENSIONS *extns)
1066 {
1067 KMF_RETURN ret = KMF_OK;
1068 BerElement *extn = NULL;
1069 BerValue *extnvalue = NULL;
1070
1071 extn = kmfder_alloc();
1072 if (extn == NULL)
1073 return (KMF_ERR_MEMORY);
1074
1075 if (kmfber_printf(extn, "{") == -1) {
1076 ret = KMF_ERR_ENCODING;
1077 goto cleanup;
1078 }
1079
1080 ret = encode_extension_list(extn, extns);
1081
1082 if (kmfber_printf(extn, "}") == -1) {
1083 ret = KMF_ERR_ENCODING;
1084 goto cleanup;
1085 }
1086
1087 if (kmfber_flatten(extn, &extnvalue) == -1) {
1088 ret = KMF_ERR_MEMORY;
1089 goto cleanup;
1090 }
1091
1092 if (kmfber_printf(asn1, "Tl", 0xA3, extnvalue->bv_len) == -1) {
1093 ret = KMF_ERR_BAD_CERT_FORMAT;
1094 goto cleanup;
1095 }
1096
1097 if (kmfber_write(asn1, extnvalue->bv_val, extnvalue->bv_len, 0) == -1) {
1098 ret = KMF_ERR_BAD_CERT_FORMAT;
1099 goto cleanup;
1100 }
1101
1102 cleanup:
1103 kmfber_free(extn, 1);
1104 if (extnvalue != NULL)
1105 kmfber_bvfree(extnvalue);
1106
1107 return (ret);
1108 }
1109
1110 static KMF_RETURN
get_one_extension(BerElement * asn1,KMF_X509_EXTENSION ** retex,char * end)1111 get_one_extension(BerElement *asn1, KMF_X509_EXTENSION **retex, char *end)
1112 {
1113 KMF_RETURN ret = KMF_OK;
1114 ber_len_t size;
1115 int critical, tag;
1116 KMF_X509_EXTENSION *ex = NULL;
1117 BerValue extOID;
1118 BerValue extValue;
1119 BerElement *extnber = NULL;
1120
1121 if (kmfber_scanf(asn1, "T", &tag) == -1) {
1122 ret = KMF_ERR_BAD_CERT_FORMAT;
1123 goto cleanup;
1124 }
1125
1126 tag = kmfber_next_element(asn1, &size, end);
1127 if (tag != BER_OBJECT_IDENTIFIER) {
1128 ret = KMF_ERR_BAD_CERT_FORMAT;
1129 goto cleanup;
1130 }
1131 if (kmfber_scanf(asn1, "D", &extOID) == -1) {
1132 ret = KMF_ERR_BAD_CERT_FORMAT;
1133 goto cleanup;
1134 }
1135
1136 tag = kmfber_next_element(asn1, &size, end);
1137 if (tag != BER_BOOLEAN) {
1138 critical = 0;
1139 if (tag != BER_OCTET_STRING)
1140 goto cleanup;
1141 } else {
1142 if (kmfber_scanf(asn1, "b", &critical) == -1)
1143 goto cleanup;
1144 }
1145
1146 tag = kmfber_next_element(asn1, &size, end);
1147 if (tag != BER_OCTET_STRING) {
1148 ret = KMF_ERR_BAD_CERT_FORMAT;
1149 goto cleanup;
1150 }
1151 if (kmfber_scanf(asn1, "o", &extValue) == -1) {
1152 ret = KMF_ERR_BAD_CERT_FORMAT;
1153 goto cleanup;
1154 }
1155
1156 /* allocate a new Extension record */
1157 ex = malloc(sizeof (KMF_X509_EXTENSION));
1158 if (ex == NULL) {
1159 ret = KMF_ERR_MEMORY;
1160 goto cleanup;
1161 }
1162 (void) memset(ex, 0, sizeof (ex));
1163
1164 ex->extnId.Data = (uchar_t *)extOID.bv_val;
1165 ex->extnId.Length = extOID.bv_len;
1166 ex->critical = critical;
1167 ex->format = KMF_X509_DATAFORMAT_ENCODED;
1168 ex->BERvalue.Data = (uchar_t *)extValue.bv_val;
1169 ex->BERvalue.Length = extValue.bv_len;
1170
1171 /* Tag and value is a little tricky */
1172 ex->value.tagAndValue = malloc(sizeof (KMF_X509EXT_TAGandVALUE));
1173 if (ex->value.tagAndValue == NULL) {
1174 ret = KMF_ERR_MEMORY;
1175 goto cleanup;
1176 }
1177 (void) memset(ex->value.tagAndValue, 0,
1178 sizeof (KMF_X509EXT_TAGandVALUE));
1179
1180 /* Parse the Extension value field */
1181 extnber = kmfder_init(&extValue);
1182 if (extnber == NULL) {
1183 ret = KMF_ERR_MEMORY;
1184 goto cleanup;
1185 }
1186
1187 /* Get the tag and length of the extension field */
1188 if (kmfber_scanf(extnber, "tl", &tag, &size) == -1) {
1189 ret = KMF_ERR_BAD_CERT_FORMAT;
1190 goto cleanup;
1191 }
1192
1193 if (kmfber_scanf(extnber, "T", &tag) == -1) {
1194 ret = KMF_ERR_BAD_CERT_FORMAT;
1195 goto cleanup;
1196 }
1197
1198 ex->value.tagAndValue->value.Data = malloc(size);
1199 ex->value.tagAndValue->value.Length = size;
1200 size = kmfber_read(extnber,
1201 (char *)ex->value.tagAndValue->value.Data, size);
1202 if (size != ex->value.tagAndValue->value.Length) {
1203 ret = KMF_ERR_BAD_CERT_FORMAT;
1204 goto cleanup;
1205 }
1206 kmfber_free(extnber, 1);
1207 ex->value.tagAndValue->type = tag;
1208
1209 *retex = ex;
1210 cleanup:
1211 if (ret != KMF_OK) {
1212 if (ex != NULL)
1213 free_one_extension(ex);
1214 }
1215
1216 return (ret);
1217 }
1218
1219 static KMF_RETURN
get_extensions(BerElement * asn1,KMF_X509_EXTENSIONS * extns)1220 get_extensions(BerElement *asn1, KMF_X509_EXTENSIONS *extns)
1221 {
1222 KMF_RETURN ret = KMF_OK;
1223 ber_len_t size;
1224 char *end = NULL;
1225 KMF_X509_EXTENSION *ex = NULL;
1226
1227 /*
1228 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
1229 *
1230 * Extension ::= SEQUENCE {
1231 * extnID OBJECT IDENTIFIER,
1232 * critical BOOLEAN DEFAULT FALSE,
1233 * extnValue OCTET STRING }
1234 *
1235 * { {{D}Bo}, ... }
1236 */
1237 if (kmfber_first_element(asn1, &size, &end) !=
1238 BER_CONSTRUCTED_SEQUENCE)
1239 return (KMF_ERR_BAD_CERT_FORMAT);
1240
1241 while (kmfber_next_element(asn1, &size, end) ==
1242 BER_CONSTRUCTED_SEQUENCE) {
1243 ret = get_one_extension(asn1, &ex, end);
1244 if (ret != KMF_OK)
1245 goto cleanup;
1246
1247 extns->numberOfExtensions++;
1248 extns->extensions = realloc(extns->extensions,
1249 extns->numberOfExtensions *
1250 sizeof (KMF_X509_EXTENSION));
1251 if (extns->extensions == NULL) {
1252 ret = KMF_ERR_MEMORY;
1253 break;
1254 }
1255
1256 extns->extensions[extns->numberOfExtensions-1] = *ex;
1257 free(ex);
1258 }
1259
1260 cleanup:
1261 if (ret != KMF_OK)
1262 free_extensions(extns);
1263
1264 return (ret);
1265 }
1266
1267 KMF_RETURN
decode_tbscert_data(BerElement * asn1,KMF_X509_TBS_CERT ** signed_cert_ptr_ptr)1268 decode_tbscert_data(BerElement *asn1,
1269 KMF_X509_TBS_CERT **signed_cert_ptr_ptr)
1270 {
1271 KMF_RETURN ret = KMF_OK;
1272 KMF_X509_TBS_CERT *tbscert = NULL;
1273 int tag, version;
1274 struct berval *bvserno = NULL;
1275 KMF_BIGINT serno;
1276
1277 if (kmfber_scanf(asn1, "{t", &tag) == -1) {
1278 ret = KMF_ERR_BAD_CERT_FORMAT;
1279 goto cleanup;
1280 }
1281
1282 /* Version number is optional */
1283 if (tag == 0xA0) {
1284 if (kmfber_scanf(asn1, "Ti", &tag, &version) == -1) {
1285 ret = KMF_ERR_BAD_CERT_FORMAT;
1286 goto cleanup;
1287 }
1288 } else {
1289 version = 0; /* DEFAULT v1 (0) */
1290 }
1291
1292 /* Now get the serial number, it is not optional */
1293 if (kmfber_scanf(asn1, "I", &bvserno) == -1) {
1294 ret = KMF_ERR_BAD_CERT_FORMAT;
1295 goto cleanup;
1296 } else {
1297 serno.val = (uchar_t *)bvserno->bv_val;
1298 serno.len = bvserno->bv_len;
1299 }
1300
1301 tbscert = malloc(sizeof (KMF_X509_TBS_CERT));
1302 if (!tbscert) {
1303 ret = KMF_ERR_MEMORY;
1304 goto cleanup;
1305 }
1306
1307 (void) memset(tbscert, 0, sizeof (KMF_X509_TBS_CERT));
1308
1309 if ((ret = set_der_integer(&tbscert->version, version)) != KMF_OK)
1310 goto cleanup;
1311
1312 if ((ret = set_bigint(&tbscert->serialNumber, &serno)) != KMF_OK)
1313 goto cleanup;
1314
1315 if ((ret = get_algoid(asn1, &tbscert->signature)) != KMF_OK)
1316 goto cleanup;
1317
1318 if ((ret = get_rdn(asn1, &tbscert->issuer)) != KMF_OK)
1319 goto cleanup;
1320
1321 if ((ret = get_validity(asn1, &tbscert->validity)) != KMF_OK)
1322 goto cleanup;
1323
1324 if ((ret = get_rdn(asn1, &tbscert->subject)) != KMF_OK)
1325 goto cleanup;
1326
1327 if ((ret = get_spki(asn1, &tbscert->subjectPublicKeyInfo)) != KMF_OK)
1328 goto cleanup;
1329
1330 /* Check for the optional fields */
1331 tbscert->extensions.numberOfExtensions = 0;
1332 tbscert->extensions.extensions = NULL;
1333
1334 while ((kmfber_scanf(asn1, "t", &tag)) != -1 &&
1335 (tag == 0xA1 || tag == 0xA2 || tag == 0xA3)) {
1336 char *optfield;
1337 ber_len_t len;
1338
1339 /* consume the tag and length */
1340 (void) kmfber_scanf(asn1, "T", &tag);
1341 switch (tag) {
1342 case 0xA1:
1343 if (kmfber_scanf(asn1, "B", &optfield, &len) !=
1344 BER_BIT_STRING) {
1345 ret = KMF_ERR_BAD_CERT_FORMAT;
1346 goto cleanup;
1347 }
1348 tbscert->issuerUniqueIdentifier.Data =
1349 (uchar_t *)optfield;
1350 tbscert->issuerUniqueIdentifier.Length =
1351 len / 8;
1352 break;
1353 case 0xA2:
1354 if (kmfber_scanf(asn1, "B", &optfield, &len) !=
1355 BER_BIT_STRING) {
1356 ret = KMF_ERR_BAD_CERT_FORMAT;
1357 goto cleanup;
1358 }
1359 tbscert->subjectUniqueIdentifier.Data =
1360 (uchar_t *)optfield;
1361 tbscert->subjectUniqueIdentifier.Length =
1362 len / 8;
1363 break;
1364 case 0xA3:
1365 ret = get_extensions(asn1, &tbscert->extensions);
1366 break;
1367 }
1368 }
1369
1370 *signed_cert_ptr_ptr = tbscert;
1371
1372 cleanup:
1373 if (bvserno != NULL) {
1374 free(bvserno->bv_val);
1375 free(bvserno);
1376 }
1377 if (ret != KMF_OK) {
1378 if (tbscert) {
1379 free_tbscert(tbscert);
1380 free(tbscert);
1381 }
1382 *signed_cert_ptr_ptr = NULL;
1383 }
1384 return (ret);
1385 }
1386
1387 KMF_RETURN
DerDecodeTbsCertificate(const KMF_DATA * Value,KMF_X509_TBS_CERT ** tbscert)1388 DerDecodeTbsCertificate(const KMF_DATA *Value,
1389 KMF_X509_TBS_CERT **tbscert)
1390 {
1391 KMF_RETURN ret = KMF_OK;
1392 BerElement *asn1 = NULL;
1393 BerValue rawcert;
1394 KMF_X509_TBS_CERT *newcert = NULL;
1395
1396 if (!tbscert || !Value || !Value->Data || !Value->Length)
1397 return (KMF_ERR_BAD_PARAMETER);
1398
1399 rawcert.bv_val = (char *)Value->Data;
1400 rawcert.bv_len = Value->Length;
1401
1402 if ((asn1 = kmfder_init(&rawcert)) == NULL)
1403 return (KMF_ERR_MEMORY);
1404
1405 ret = decode_tbscert_data(asn1, &newcert);
1406 if (ret != KMF_OK)
1407 goto cleanup;
1408
1409 *tbscert = newcert;
1410
1411 cleanup:
1412 if (ret != KMF_OK) {
1413 if (newcert)
1414 free_tbscert(newcert);
1415 *tbscert = NULL;
1416 }
1417 kmfber_free(asn1, 1);
1418
1419 return (ret);
1420 }
1421
1422 /*
1423 * Name: DerDecodeSignedCertificate
1424 *
1425 * Description:
1426 * DER decodes the encoded X509 certificate
1427 *
1428 * Parameters:
1429 * Value (input): DER encoded object that shd be decoded
1430 *
1431 * signed_cert_ptr_ptr (output) : Decoded KMF_X509_CERTIFICATE object
1432 */
1433 KMF_RETURN
DerDecodeSignedCertificate(const KMF_DATA * Value,KMF_X509_CERTIFICATE ** signed_cert_ptr_ptr)1434 DerDecodeSignedCertificate(const KMF_DATA *Value,
1435 KMF_X509_CERTIFICATE **signed_cert_ptr_ptr)
1436 {
1437 KMF_RETURN ret = KMF_OK;
1438 BerElement *asn1 = NULL;
1439 BerValue rawcert;
1440 ber_tag_t tag;
1441 ber_len_t size;
1442 char *end = NULL;
1443 char *signature;
1444 KMF_X509_TBS_CERT *tbscert = NULL;
1445 KMF_X509_CERTIFICATE *certptr = NULL;
1446
1447 if (!signed_cert_ptr_ptr || !Value || !Value->Data || !Value->Length)
1448 return (KMF_ERR_BAD_PARAMETER);
1449
1450 rawcert.bv_val = (char *)Value->Data;
1451 rawcert.bv_len = Value->Length;
1452
1453 if ((asn1 = kmfder_init(&rawcert)) == NULL)
1454 return (KMF_ERR_MEMORY);
1455
1456 if (kmfber_first_element(asn1, &size, &end) !=
1457 BER_CONSTRUCTED_SEQUENCE) {
1458 ret = KMF_ERR_BAD_CERT_FORMAT;
1459 goto cleanup;
1460 }
1461
1462 certptr = malloc(sizeof (KMF_X509_CERTIFICATE));
1463 if (certptr == NULL) {
1464 ret = KMF_ERR_MEMORY;
1465 goto cleanup;
1466 }
1467 (void) memset(certptr, 0, sizeof (KMF_X509_CERTIFICATE));
1468
1469 ret = decode_tbscert_data(asn1, &tbscert);
1470 if (ret != KMF_OK)
1471 goto cleanup;
1472
1473 certptr->certificate = *tbscert;
1474 free(tbscert);
1475 tbscert = NULL;
1476
1477 /*
1478 * The signature data my not be present yet.
1479 */
1480 if ((ret = get_algoid(asn1,
1481 &certptr->signature.algorithmIdentifier)) == KMF_OK) {
1482
1483 /* Check to see if the cert has a signature yet */
1484 if (kmfber_next_element(asn1, &size, end) == BER_BIT_STRING) {
1485 /* Finally, get the encrypted signature BITSTRING */
1486 if (kmfber_scanf(asn1, "tl", &tag, &size) == -1) {
1487 ret = KMF_ERR_BAD_CERT_FORMAT;
1488 goto cleanup;
1489 }
1490 if (tag != BER_BIT_STRING) {
1491 ret = KMF_ERR_BAD_CERT_FORMAT;
1492 goto cleanup;
1493 }
1494 if (kmfber_scanf(asn1, "B}", &signature, &size) == -1) {
1495 ret = KMF_ERR_BAD_CERT_FORMAT;
1496 goto cleanup;
1497 }
1498 certptr->signature.encrypted.Data =
1499 (uchar_t *)signature;
1500 certptr->signature.encrypted.Length = size / 8;
1501 } else {
1502 certptr->signature.encrypted.Data = NULL;
1503 certptr->signature.encrypted.Length = 0;
1504 }
1505 } else {
1506 (void) memset(&certptr->signature, 0,
1507 sizeof (certptr->signature));
1508 ret = KMF_OK;
1509 }
1510
1511 *signed_cert_ptr_ptr = certptr;
1512 cleanup:
1513 if (ret != KMF_OK) {
1514 if (certptr) {
1515 free_decoded_cert(certptr);
1516 free(certptr);
1517 }
1518
1519 *signed_cert_ptr_ptr = NULL;
1520 }
1521 if (asn1)
1522 kmfber_free(asn1, 1);
1523
1524 return (ret);
1525
1526 }
1527
1528 KMF_RETURN
DerDecodeExtension(KMF_DATA * Data,KMF_X509_EXTENSION ** extn)1529 DerDecodeExtension(KMF_DATA *Data, KMF_X509_EXTENSION **extn)
1530 {
1531 KMF_RETURN ret = KMF_OK;
1532 BerElement *asn1 = NULL;
1533 BerValue bv;
1534
1535 bv.bv_val = (char *)Data->Data;
1536 bv.bv_len = Data->Length;
1537
1538 asn1 = kmfder_init(&bv);
1539 if (asn1 == NULL)
1540 return (KMF_ERR_MEMORY);
1541
1542 ret = get_one_extension(asn1, extn, NULL);
1543
1544 cleanup:
1545 if (ret != KMF_OK) {
1546 if (*extn != NULL) {
1547 free(*extn);
1548 }
1549 *extn = NULL;
1550 }
1551
1552 kmfber_free(asn1, 1);
1553 return (ret);
1554 }
1555
1556 KMF_RETURN
DerDecodeName(KMF_DATA * encodedname,KMF_X509_NAME * name)1557 DerDecodeName(KMF_DATA *encodedname, KMF_X509_NAME *name)
1558 {
1559 KMF_RETURN ret = KMF_OK;
1560 BerElement *asn1 = NULL;
1561 BerValue bv;
1562
1563 bv.bv_val = (char *)encodedname->Data;
1564 bv.bv_len = encodedname->Length;
1565
1566 asn1 = kmfder_init(&bv);
1567 if (asn1 == NULL)
1568 return (KMF_ERR_MEMORY);
1569
1570 (void) memset((void *)name, 0, sizeof (KMF_X509_NAME));
1571
1572 if ((ret = get_rdn(asn1, name)) != KMF_OK)
1573 goto cleanup;
1574
1575 cleanup:
1576 if (asn1)
1577 kmfber_free(asn1, 1);
1578 return (ret);
1579 }
1580
1581 KMF_RETURN
DerEncodeName(KMF_X509_NAME * name,KMF_DATA * encodedname)1582 DerEncodeName(KMF_X509_NAME *name, KMF_DATA *encodedname)
1583 {
1584 KMF_RETURN ret = KMF_OK;
1585 BerElement *asn1 = NULL;
1586 BerValue *bv = NULL;
1587
1588 asn1 = kmfder_alloc();
1589 if (asn1 == NULL)
1590 return (KMF_ERR_MEMORY);
1591
1592 if ((ret = encode_rdn(asn1, name)) != KMF_OK)
1593 goto cleanup;
1594
1595 if (kmfber_flatten(asn1, &bv) == -1) {
1596 ret = KMF_ERR_BAD_CERT_FORMAT;
1597 goto cleanup;
1598 }
1599
1600 encodedname->Data = (uchar_t *)bv->bv_val;
1601 encodedname->Length = bv->bv_len;
1602
1603 cleanup:
1604 if (bv)
1605 free(bv);
1606
1607 if (asn1)
1608 kmfber_free(asn1, 1);
1609
1610 return (ret);
1611 }
1612
1613 static KMF_RETURN
encode_tbs_cert(BerElement * asn1,KMF_X509_TBS_CERT * tbscert)1614 encode_tbs_cert(BerElement *asn1, KMF_X509_TBS_CERT *tbscert)
1615 {
1616 KMF_RETURN ret = KMF_OK;
1617 uint32_t version;
1618
1619 /* version should be 4 bytes or less */
1620 if (tbscert->version.Length > sizeof (int))
1621 return (KMF_ERR_BAD_CERT_FORMAT);
1622
1623 (void) memcpy(&version, tbscert->version.Data,
1624 tbscert->version.Length);
1625
1626 /* Start the sequence and add the version */
1627 if (kmfber_printf(asn1, "{Tli", 0xA0, 3, version) == -1) {
1628 ret = KMF_ERR_BAD_CERT_FORMAT;
1629 goto cleanup;
1630 }
1631 /* Write the serial number */
1632 if (kmfber_printf(asn1, "I",
1633 (char *)tbscert->serialNumber.val,
1634 (size_t)tbscert->serialNumber.len) == -1) {
1635 ret = KMF_ERR_BAD_CERT_FORMAT;
1636 goto cleanup;
1637 }
1638
1639 /* Don't encode alg parameters in signature algid area */
1640 if ((ret = encode_algoid(asn1, &tbscert->signature, FALSE)) != KMF_OK)
1641 goto cleanup;
1642
1643 /* Encode the Issuer RDN */
1644 if ((ret = encode_rdn(asn1, &tbscert->issuer)) != KMF_OK)
1645 goto cleanup;
1646
1647 /* Encode the Validity fields */
1648 if ((ret = encode_validity(asn1, &tbscert->validity)) != KMF_OK)
1649 goto cleanup;
1650
1651 /* Encode the Subject RDN */
1652 if ((ret = encode_rdn(asn1, &tbscert->subject)) != KMF_OK)
1653 goto cleanup;
1654
1655 /* Encode the Subject Public Key Info */
1656 if ((ret = encode_spki(asn1, &tbscert->subjectPublicKeyInfo)) != KMF_OK)
1657 goto cleanup;
1658
1659 /* Optional field: issuer Unique ID */
1660 if (tbscert->issuerUniqueIdentifier.Length > 0) {
1661 if ((ret = encode_uniqueid(asn1, 0xA1,
1662 &tbscert->issuerUniqueIdentifier)) != KMF_OK)
1663 goto cleanup;
1664 }
1665
1666 /* Optional field: Subject Unique ID */
1667 if (tbscert->subjectUniqueIdentifier.Length > 0) {
1668 if ((ret = encode_uniqueid(asn1, 0xA2,
1669 &tbscert->subjectUniqueIdentifier)) != KMF_OK)
1670 goto cleanup;
1671 }
1672
1673 /* Optional field: Certificate Extensions */
1674 if (tbscert->extensions.numberOfExtensions > 0) {
1675 if ((ret = encode_extensions(asn1,
1676 &tbscert->extensions)) != KMF_OK)
1677 goto cleanup;
1678 }
1679
1680 /* Close out the TBSCert sequence */
1681 if (kmfber_printf(asn1, "}") == -1) {
1682 ret = KMF_ERR_BAD_CERT_FORMAT;
1683 goto cleanup;
1684 }
1685
1686 cleanup:
1687 /*
1688 * Memory cleanup is done in the caller or in the individual
1689 * encoding routines.
1690 */
1691
1692 return (ret);
1693 }
1694
1695 KMF_RETURN
DerEncodeTbsCertificate(KMF_X509_TBS_CERT * tbs_cert_ptr,KMF_DATA * enc_tbs_cert_ptr)1696 DerEncodeTbsCertificate(KMF_X509_TBS_CERT *tbs_cert_ptr,
1697 KMF_DATA *enc_tbs_cert_ptr)
1698 {
1699 KMF_RETURN ret;
1700 BerElement *asn1 = NULL;
1701 BerValue *tbsdata = NULL;
1702
1703 asn1 = kmfder_alloc();
1704 if (asn1 == NULL)
1705 return (KMF_ERR_MEMORY);
1706
1707 enc_tbs_cert_ptr->Data = NULL;
1708 enc_tbs_cert_ptr->Length = 0;
1709
1710 ret = encode_tbs_cert(asn1, tbs_cert_ptr);
1711 if (ret != KMF_OK)
1712 goto cleanup;
1713
1714 if (kmfber_flatten(asn1, &tbsdata) == -1) {
1715 ret = KMF_ERR_MEMORY;
1716 goto cleanup;
1717 }
1718
1719 enc_tbs_cert_ptr->Data = (uchar_t *)tbsdata->bv_val;
1720 enc_tbs_cert_ptr->Length = tbsdata->bv_len;
1721
1722 cleanup:
1723 if (ret != KMF_OK)
1724 free_data(enc_tbs_cert_ptr);
1725
1726 if (asn1 != NULL)
1727 kmfber_free(asn1, 1);
1728
1729 if (tbsdata)
1730 free(tbsdata);
1731
1732 return (ret);
1733 }
1734
1735 KMF_RETURN
DerEncodeSignedCertificate(KMF_X509_CERTIFICATE * signed_cert_ptr,KMF_DATA * encodedcert)1736 DerEncodeSignedCertificate(KMF_X509_CERTIFICATE *signed_cert_ptr,
1737 KMF_DATA *encodedcert)
1738 {
1739 KMF_RETURN ret = KMF_OK;
1740 KMF_X509_TBS_CERT *tbscert = NULL;
1741 KMF_X509_SIGNATURE *signature = NULL;
1742 BerElement *asn1 = NULL;
1743 BerValue *tbsdata = NULL;
1744
1745 if (signed_cert_ptr == NULL || encodedcert == NULL)
1746 return (KMF_ERR_BAD_PARAMETER);
1747
1748 encodedcert->Data = NULL;
1749 encodedcert->Length = 0;
1750
1751 tbscert = &signed_cert_ptr->certificate;
1752 signature = &signed_cert_ptr->signature;
1753
1754 asn1 = kmfder_alloc();
1755 if (asn1 == NULL)
1756 return (KMF_ERR_MEMORY);
1757
1758 /* Start outer X509 Certificate SEQUENCE */
1759 if (kmfber_printf(asn1, "{") == -1) {
1760 ret = KMF_ERR_BAD_CERT_FORMAT;
1761 goto cleanup;
1762 }
1763
1764 if ((ret = encode_tbs_cert(asn1, tbscert)) != KMF_OK) {
1765 ret = KMF_ERR_BAD_CERT_FORMAT;
1766 goto cleanup;
1767 }
1768
1769 /* Add the Algorithm & Signature Sequence (no parameters) */
1770 if ((ret = encode_algoid(asn1,
1771 &signature->algorithmIdentifier, FALSE)) != KMF_OK)
1772 goto cleanup;
1773
1774 if (signature->encrypted.Length > 0) {
1775 if (kmfber_printf(asn1, "B", signature->encrypted.Data,
1776 signature->encrypted.Length * 8) == -1) {
1777 ret = KMF_ERR_BAD_CERT_FORMAT;
1778 goto cleanup;
1779 }
1780 }
1781
1782 if (kmfber_printf(asn1, "}") == -1) {
1783 ret = KMF_ERR_BAD_CERT_FORMAT;
1784 goto cleanup;
1785 }
1786
1787 if (kmfber_flatten(asn1, &tbsdata) == -1) {
1788 ret = KMF_ERR_MEMORY;
1789 goto cleanup;
1790 }
1791
1792 encodedcert->Data = (uchar_t *)tbsdata->bv_val;
1793 encodedcert->Length = tbsdata->bv_len;
1794
1795 cleanup:
1796 if (ret != KMF_OK)
1797 free_data(encodedcert);
1798
1799 if (tbsdata)
1800 free(tbsdata);
1801
1802 if (asn1)
1803 kmfber_free(asn1, 1);
1804
1805 return (ret);
1806 }
1807
1808 KMF_RETURN
ExtractX509CertParts(KMF_DATA * x509cert,KMF_DATA * tbscert,KMF_DATA * signature)1809 ExtractX509CertParts(KMF_DATA *x509cert, KMF_DATA *tbscert,
1810 KMF_DATA *signature)
1811 {
1812 KMF_RETURN ret = KMF_OK;
1813 BerElement *der = NULL;
1814 BerValue x509;
1815 ber_tag_t tag;
1816 ber_len_t size;
1817
1818 if (tbscert == NULL || x509cert == NULL)
1819 return (KMF_ERR_BAD_PARAMETER);
1820
1821 x509.bv_val = (char *)x509cert->Data;
1822 x509.bv_len = x509cert->Length;
1823
1824 der = kmfder_init(&x509);
1825 if (der == NULL)
1826 return (KMF_ERR_MEMORY);
1827
1828 /* Skip over the overall Sequence tag to get at the TBS Cert data */
1829 if (kmfber_scanf(der, "Tl", &tag, &size) == -1) {
1830 ret = KMF_ERR_BAD_CERT_FORMAT;
1831 goto cleanup;
1832 }
1833 if (tag != BER_CONSTRUCTED_SEQUENCE) {
1834 ret = KMF_ERR_BAD_CERT_FORMAT;
1835 goto cleanup;
1836 }
1837
1838 /*
1839 * Since we are extracting a copy of the ENCODED bytes, we
1840 * must make sure to also include the bytes for the tag and
1841 * the length fields for the CONSTRUCTED SEQUENCE (TBSCert).
1842 */
1843 size += kmfber_calc_taglen(tag) + kmfber_calc_lenlen(size);
1844
1845 tbscert->Data = malloc(size);
1846 if (tbscert->Data == NULL) {
1847 ret = KMF_ERR_MEMORY;
1848 goto cleanup;
1849 }
1850 tbscert->Length = size;
1851
1852 /* The der data ptr is now set to the start of the TBS cert sequence */
1853 size = kmfber_read(der, (char *)tbscert->Data, tbscert->Length);
1854 if (size != tbscert->Length) {
1855 ret = KMF_ERR_BAD_CERT_FORMAT;
1856 goto cleanup;
1857 }
1858
1859 if (signature != NULL) {
1860 KMF_X509_ALGORITHM_IDENTIFIER algoid;
1861 if ((ret = get_algoid(der, &algoid)) != KMF_OK)
1862 goto cleanup;
1863 free_algoid(&algoid);
1864
1865 if (kmfber_scanf(der, "tl", &tag, &size) != BER_BIT_STRING) {
1866 ret = KMF_ERR_BAD_CERT_FORMAT;
1867 goto cleanup;
1868 }
1869 /* Now get the signature data */
1870 if (kmfber_scanf(der, "B", (char **)&signature->Data,
1871 (ber_len_t *)&signature->Length) == -1) {
1872 ret = KMF_ERR_BAD_CERT_FORMAT;
1873 goto cleanup;
1874 }
1875 /* convert bitstring length to bytes */
1876 signature->Length = signature->Length / 8;
1877 }
1878
1879 cleanup:
1880 if (der)
1881 kmfber_free(der, 1);
1882
1883 if (ret != KMF_OK)
1884 free_data(tbscert);
1885
1886 return (ret);
1887 }
1888
1889 static KMF_RETURN
decode_csr_extensions(BerElement * asn1,KMF_X509_EXTENSIONS * extns)1890 decode_csr_extensions(BerElement *asn1, KMF_X509_EXTENSIONS *extns)
1891 {
1892 KMF_RETURN ret = KMF_OK;
1893 BerValue oid;
1894
1895 if (kmfber_scanf(asn1, "{D", &oid) == -1) {
1896 return (KMF_ERR_UNKNOWN_CSR_ATTRIBUTE);
1897 }
1898
1899 /* We only understand extension requests in a CSR */
1900 if (memcmp(oid.bv_val, extension_request_oid.Data,
1901 oid.bv_len) != 0) {
1902 return (KMF_ERR_UNKNOWN_CSR_ATTRIBUTE);
1903 }
1904
1905 if (kmfber_scanf(asn1, "[") == -1) {
1906 return (KMF_ERR_ENCODING);
1907 }
1908 ret = get_extensions(asn1, extns);
1909
1910
1911 return (ret);
1912 }
1913
1914 static KMF_RETURN
decode_tbscsr_data(BerElement * asn1,KMF_TBS_CSR ** signed_csr_ptr_ptr)1915 decode_tbscsr_data(BerElement *asn1,
1916 KMF_TBS_CSR **signed_csr_ptr_ptr)
1917 {
1918 KMF_RETURN ret = KMF_OK;
1919 KMF_TBS_CSR *tbscsr = NULL;
1920 char *end = NULL;
1921 uint32_t version;
1922 ber_tag_t tag;
1923 ber_len_t size;
1924
1925 /* Now get the version number, it is not optional */
1926 if (kmfber_scanf(asn1, "{i", &version) == -1) {
1927 ret = KMF_ERR_BAD_CERT_FORMAT;
1928 goto cleanup;
1929 }
1930
1931 tbscsr = malloc(sizeof (KMF_TBS_CSR));
1932 if (!tbscsr) {
1933 ret = KMF_ERR_MEMORY;
1934 goto cleanup;
1935 }
1936
1937 (void) memset(tbscsr, 0, sizeof (KMF_TBS_CSR));
1938
1939 if ((ret = set_der_integer(&tbscsr->version, version)) != KMF_OK)
1940 goto cleanup;
1941
1942 if ((ret = get_rdn(asn1, &tbscsr->subject)) != KMF_OK)
1943 goto cleanup;
1944
1945 if ((ret = get_spki(asn1, &tbscsr->subjectPublicKeyInfo)) != KMF_OK)
1946 goto cleanup;
1947
1948 /* Check for the optional fields (attributes) */
1949 if (kmfber_next_element(asn1, &size, end) == 0xA0) {
1950 if (kmfber_scanf(asn1, "Tl", &tag, &size) == -1) {
1951 ret = KMF_ERR_ENCODING;
1952 goto cleanup;
1953 }
1954
1955 ret = decode_csr_extensions(asn1, &tbscsr->extensions);
1956 }
1957 if (ret == KMF_OK)
1958 *signed_csr_ptr_ptr = tbscsr;
1959
1960 cleanup:
1961 if (ret != KMF_OK) {
1962 if (tbscsr) {
1963 free_tbscsr(tbscsr);
1964 free(tbscsr);
1965 }
1966 *signed_csr_ptr_ptr = NULL;
1967 }
1968 return (ret);
1969 }
1970
1971 KMF_RETURN
DerDecodeTbsCsr(const KMF_DATA * Value,KMF_TBS_CSR ** tbscsr)1972 DerDecodeTbsCsr(const KMF_DATA *Value,
1973 KMF_TBS_CSR **tbscsr)
1974 {
1975 KMF_RETURN ret = KMF_OK;
1976 BerElement *asn1 = NULL;
1977 BerValue rawcsr;
1978 KMF_TBS_CSR *newcsr = NULL;
1979
1980 if (!tbscsr || !Value || !Value->Data || !Value->Length)
1981 return (KMF_ERR_BAD_PARAMETER);
1982
1983 rawcsr.bv_val = (char *)Value->Data;
1984 rawcsr.bv_len = Value->Length;
1985
1986 if ((asn1 = kmfder_init(&rawcsr)) == NULL)
1987 return (KMF_ERR_MEMORY);
1988
1989 ret = decode_tbscsr_data(asn1, &newcsr);
1990 if (ret != KMF_OK)
1991 goto cleanup;
1992
1993 *tbscsr = newcsr;
1994
1995 cleanup:
1996 if (ret != KMF_OK) {
1997 if (newcsr)
1998 free_tbscsr(newcsr);
1999 *tbscsr = NULL;
2000 }
2001 kmfber_free(asn1, 1);
2002
2003 return (ret);
2004 }
2005
2006 KMF_RETURN
DerDecodeSignedCsr(const KMF_DATA * Value,KMF_CSR_DATA ** signed_csr_ptr_ptr)2007 DerDecodeSignedCsr(const KMF_DATA *Value,
2008 KMF_CSR_DATA **signed_csr_ptr_ptr)
2009 {
2010 KMF_RETURN ret = KMF_OK;
2011 BerElement *asn1 = NULL;
2012 BerValue rawcsr;
2013 int tag;
2014 ber_len_t size;
2015 char *end = NULL;
2016 char *signature;
2017 KMF_TBS_CSR *tbscsr = NULL;
2018 KMF_CSR_DATA *csrptr = NULL;
2019
2020 if (!signed_csr_ptr_ptr || !Value || !Value->Data || !Value->Length)
2021 return (KMF_ERR_BAD_PARAMETER);
2022
2023 rawcsr.bv_val = (char *)Value->Data;
2024 rawcsr.bv_len = Value->Length;
2025
2026 if ((asn1 = kmfder_init(&rawcsr)) == NULL)
2027 return (KMF_ERR_MEMORY);
2028
2029 if (kmfber_first_element(asn1, &size, &end) !=
2030 BER_CONSTRUCTED_SEQUENCE) {
2031 ret = KMF_ERR_BAD_CERT_FORMAT;
2032 goto cleanup;
2033 }
2034
2035 csrptr = malloc(sizeof (KMF_CSR_DATA));
2036 if (csrptr == NULL) {
2037 ret = KMF_ERR_MEMORY;
2038 goto cleanup;
2039 }
2040 (void) memset(csrptr, 0, sizeof (KMF_CSR_DATA));
2041
2042 ret = decode_tbscsr_data(asn1, &tbscsr);
2043 if (ret != KMF_OK)
2044 goto cleanup;
2045
2046 csrptr->csr = *tbscsr;
2047 free(tbscsr);
2048 tbscsr = NULL;
2049
2050 if ((ret = get_algoid(asn1,
2051 &csrptr->signature.algorithmIdentifier)) != KMF_OK)
2052 goto cleanup;
2053
2054 /* Check to see if the cert has a signature yet */
2055 if (kmfber_next_element(asn1, &size, end) == BER_BIT_STRING) {
2056 /* Finally, get the encrypted signature BITSTRING */
2057 if (kmfber_scanf(asn1, "tl", &tag, &size) == -1) {
2058 ret = KMF_ERR_BAD_CERT_FORMAT;
2059 goto cleanup;
2060 }
2061 if (tag != BER_BIT_STRING) {
2062 ret = KMF_ERR_BAD_CERT_FORMAT;
2063 goto cleanup;
2064 }
2065 if (kmfber_scanf(asn1, "B}", &signature, &size) == -1) {
2066 ret = KMF_ERR_BAD_CERT_FORMAT;
2067 goto cleanup;
2068 }
2069 csrptr->signature.encrypted.Data = (uchar_t *)signature;
2070 csrptr->signature.encrypted.Length = size / 8;
2071 } else {
2072 csrptr->signature.encrypted.Data = NULL;
2073 csrptr->signature.encrypted.Length = 0;
2074 }
2075
2076 *signed_csr_ptr_ptr = csrptr;
2077 cleanup:
2078 if (ret != KMF_OK) {
2079 free_tbscsr(&csrptr->csr);
2080 free_algoid(&csrptr->signature.algorithmIdentifier);
2081 if (csrptr->signature.encrypted.Data)
2082 free(csrptr->signature.encrypted.Data);
2083
2084 if (csrptr)
2085 free(csrptr);
2086
2087 *signed_csr_ptr_ptr = NULL;
2088 }
2089 if (asn1)
2090 kmfber_free(asn1, 1);
2091
2092 return (ret);
2093
2094 }
2095
2096 static KMF_RETURN
encode_csr_extensions(BerElement * asn1,KMF_TBS_CSR * tbscsr)2097 encode_csr_extensions(BerElement *asn1, KMF_TBS_CSR *tbscsr)
2098 {
2099 KMF_RETURN ret = KMF_OK;
2100 int attlen = 0;
2101 BerElement *extnasn1 = NULL;
2102 BerValue *extnvalue = NULL;
2103
2104 /* Optional field: CSR attributes and extensions */
2105 if (tbscsr->extensions.numberOfExtensions > 0) {
2106 if (kmfber_printf(asn1, "T", 0xA0) == -1) {
2107 ret = KMF_ERR_ENCODING;
2108 goto cleanup;
2109 }
2110 } else {
2111 /* No extensions or attributes to encode */
2112 return (KMF_OK);
2113 }
2114
2115 /*
2116 * attributes [0] Attributes
2117 * Attributes := SET OF Attribute
2118 * Attribute := SEQUENCE {
2119 * { ATTRIBUTE ID
2120 * values SET SIZE(1..MAX) of ATTRIBUTE
2121 * }
2122 *
2123 * Ex: { ExtensionRequest OID [ { {extn1 } , {extn2 } } ] }
2124 */
2125
2126 /*
2127 * Encode any extensions and add to the attributes section.
2128 */
2129 if (tbscsr->extensions.numberOfExtensions > 0) {
2130 extnasn1 = kmfder_alloc();
2131 if (extnasn1 == NULL) {
2132 ret = KMF_ERR_MEMORY;
2133 goto cleanup;
2134 }
2135
2136 if (kmfber_printf(extnasn1, "{D[{",
2137 &extension_request_oid) == -1) {
2138 ret = KMF_ERR_ENCODING;
2139 goto cleanup_1;
2140 }
2141
2142 if ((ret = encode_extension_list(extnasn1,
2143 &tbscsr->extensions)) != KMF_OK) {
2144 goto cleanup_1;
2145 }
2146
2147 if (kmfber_printf(extnasn1, "}]}") == -1) {
2148 ret = KMF_ERR_ENCODING;
2149 goto cleanup_1;
2150 }
2151
2152 if (kmfber_flatten(extnasn1, &extnvalue) == -1) {
2153 ret = KMF_ERR_MEMORY;
2154 goto cleanup_1;
2155 }
2156 cleanup_1:
2157 kmfber_free(extnasn1, 1);
2158
2159 if (ret == KMF_OK)
2160 /* Add 2 bytes to cover the tag and the length */
2161 attlen = extnvalue->bv_len;
2162 }
2163 if (ret != KMF_OK)
2164 goto cleanup;
2165
2166 if (kmfber_printf(asn1, "l", attlen) == -1) {
2167 ret = KMF_ERR_ENCODING;
2168 goto cleanup;
2169 }
2170
2171 /* Write the actual encoded extensions */
2172 if (extnvalue != NULL && extnvalue->bv_val != NULL) {
2173 if (kmfber_write(asn1, extnvalue->bv_val,
2174 extnvalue->bv_len, 0) == -1) {
2175 ret = KMF_ERR_ENCODING;
2176 goto cleanup;
2177 }
2178 }
2179
2180 cleanup:
2181 /*
2182 * Memory cleanup is done in the caller or in the individual
2183 * encoding routines.
2184 */
2185 if (extnvalue) {
2186 if (extnvalue->bv_val)
2187 free(extnvalue->bv_val);
2188 free(extnvalue);
2189 }
2190
2191 return (ret);
2192 }
2193
2194 static KMF_RETURN
encode_tbs_csr(BerElement * asn1,KMF_TBS_CSR * tbscsr)2195 encode_tbs_csr(BerElement *asn1, KMF_TBS_CSR *tbscsr)
2196 {
2197 KMF_RETURN ret = KMF_OK;
2198 uint32_t version;
2199
2200 /* Start the version */
2201 (void) memcpy(&version, tbscsr->version.Data,
2202 tbscsr->version.Length);
2203
2204 if (kmfber_printf(asn1, "{i", version) == -1) {
2205 ret = KMF_ERR_BAD_CERT_FORMAT;
2206 goto cleanup;
2207 }
2208
2209 /* Encode the Subject RDN */
2210 if ((ret = encode_rdn(asn1, &tbscsr->subject)) != KMF_OK)
2211 goto cleanup;
2212
2213 /* Encode the Subject Public Key Info */
2214 if ((ret = encode_spki(asn1, &tbscsr->subjectPublicKeyInfo)) != KMF_OK)
2215 goto cleanup;
2216
2217 if ((ret = encode_csr_extensions(asn1, tbscsr)) != KMF_OK)
2218 goto cleanup;
2219
2220 /* Close out the TBSCert sequence */
2221 if (kmfber_printf(asn1, "}") == -1) {
2222 ret = KMF_ERR_BAD_CERT_FORMAT;
2223 goto cleanup;
2224 }
2225
2226 cleanup:
2227 return (ret);
2228 }
2229
2230 KMF_RETURN
DerEncodeDSAPrivateKey(KMF_DATA * encodedkey,KMF_RAW_DSA_KEY * dsa)2231 DerEncodeDSAPrivateKey(KMF_DATA *encodedkey, KMF_RAW_DSA_KEY *dsa)
2232 {
2233 KMF_RETURN rv = KMF_OK;
2234 BerElement *asn1 = NULL;
2235 BerValue *dsadata = NULL;
2236
2237 asn1 = kmfder_alloc();
2238 if (asn1 == NULL)
2239 return (KMF_ERR_MEMORY);
2240
2241 if (kmfber_printf(asn1, "I",
2242 dsa->value.val, dsa->value.len) == -1) {
2243 rv = KMF_ERR_MEMORY;
2244 goto cleanup;
2245 }
2246
2247 if (kmfber_flatten(asn1, &dsadata) == -1) {
2248 rv = KMF_ERR_MEMORY;
2249 goto cleanup;
2250 }
2251
2252 encodedkey->Data = (uchar_t *)dsadata->bv_val;
2253 encodedkey->Length = dsadata->bv_len;
2254
2255 free(dsadata);
2256 cleanup:
2257 kmfber_free(asn1, 1);
2258 return (rv);
2259 }
2260
2261 KMF_RETURN
DerEncodeRSAPrivateKey(KMF_DATA * encodedkey,KMF_RAW_RSA_KEY * rsa)2262 DerEncodeRSAPrivateKey(KMF_DATA *encodedkey, KMF_RAW_RSA_KEY *rsa)
2263 {
2264 KMF_RETURN rv = KMF_OK;
2265 BerElement *asn1 = NULL;
2266 uchar_t ver = 0;
2267 BerValue *rsadata = NULL;
2268
2269 asn1 = kmfder_alloc();
2270 if (asn1 == NULL)
2271 return (KMF_ERR_MEMORY);
2272
2273 if (kmfber_printf(asn1, "{IIIIIIIII}",
2274 &ver, 1,
2275 rsa->mod.val, rsa->mod.len,
2276 rsa->pubexp.val, rsa->pubexp.len,
2277 rsa->priexp.val, rsa->priexp.len,
2278 rsa->prime1.val, rsa->prime1.len,
2279 rsa->prime2.val, rsa->prime2.len,
2280 rsa->exp1.val, rsa->exp1.len,
2281 rsa->exp2.val, rsa->exp2.len,
2282 rsa->coef.val, rsa->coef.len) == -1)
2283 goto cleanup;
2284
2285 if (kmfber_flatten(asn1, &rsadata) == -1) {
2286 rv = KMF_ERR_MEMORY;
2287 goto cleanup;
2288 }
2289
2290 encodedkey->Data = (uchar_t *)rsadata->bv_val;
2291 encodedkey->Length = rsadata->bv_len;
2292
2293 free(rsadata);
2294 cleanup:
2295 kmfber_free(asn1, 1);
2296 return (rv);
2297 }
2298
2299 KMF_RETURN
DerEncodeECPrivateKey(KMF_DATA * encodedkey,KMF_RAW_EC_KEY * eckey)2300 DerEncodeECPrivateKey(KMF_DATA *encodedkey, KMF_RAW_EC_KEY *eckey)
2301 {
2302 KMF_RETURN rv = KMF_OK;
2303 BerElement *asn1 = NULL;
2304 uchar_t ver = 1;
2305 BerValue *data = NULL;
2306
2307 asn1 = kmfder_alloc();
2308 if (asn1 == NULL)
2309 return (KMF_ERR_MEMORY);
2310
2311 if (kmfber_printf(asn1, "{io",
2312 ver, eckey->value.val, eckey->value.len) == -1) {
2313 rv = KMF_ERR_ENCODING;
2314 goto cleanup;
2315 }
2316 /*
2317 * Indicate that we are using the named curve option
2318 * for the parameters.
2319 */
2320 if (kmfber_printf(asn1, "T", 0xA0) == -1) {
2321 rv = KMF_ERR_ENCODING;
2322 goto cleanup;
2323 }
2324 if (kmfber_printf(asn1, "l", eckey->params.Length) == -1) {
2325 rv = KMF_ERR_ENCODING;
2326 goto cleanup;
2327 }
2328 if (kmfber_write(asn1, (char *)eckey->params.Data,
2329 eckey->params.Length, 0) == -1) {
2330 rv = KMF_ERR_ENCODING;
2331 goto cleanup;
2332 }
2333 if (kmfber_printf(asn1, "}") == -1) {
2334 rv = KMF_ERR_ENCODING;
2335 goto cleanup;
2336 }
2337 if (kmfber_flatten(asn1, &data) == -1) {
2338 rv = KMF_ERR_MEMORY;
2339 goto cleanup;
2340 }
2341 encodedkey->Data = (uchar_t *)data->bv_val;
2342 encodedkey->Length = data->bv_len;
2343
2344 cleanup:
2345 kmfber_free(asn1, 1);
2346 return (rv);
2347 }
2348
2349
2350 KMF_RETURN
DerEncodeTbsCsr(KMF_TBS_CSR * tbs_csr_ptr,KMF_DATA * enc_tbs_csr_ptr)2351 DerEncodeTbsCsr(KMF_TBS_CSR *tbs_csr_ptr,
2352 KMF_DATA *enc_tbs_csr_ptr)
2353 {
2354 KMF_RETURN ret;
2355 BerValue *tbsdata = NULL;
2356 BerElement *asn1 = NULL;
2357
2358 asn1 = kmfder_alloc();
2359
2360 enc_tbs_csr_ptr->Data = NULL;
2361 enc_tbs_csr_ptr->Length = 0;
2362
2363 if (asn1 == NULL)
2364 return (KMF_ERR_MEMORY);
2365
2366 ret = encode_tbs_csr(asn1, tbs_csr_ptr);
2367 if (ret != KMF_OK)
2368 goto cleanup;
2369
2370 if (kmfber_flatten(asn1, &tbsdata) == -1) {
2371 ret = KMF_ERR_MEMORY;
2372 goto cleanup;
2373 }
2374
2375 enc_tbs_csr_ptr->Data = (uchar_t *)tbsdata->bv_val;
2376 enc_tbs_csr_ptr->Length = tbsdata->bv_len;
2377
2378 cleanup:
2379 if (ret != KMF_OK)
2380 free_data(enc_tbs_csr_ptr);
2381
2382 if (asn1 != NULL)
2383 kmfber_free(asn1, 1);
2384
2385 if (tbsdata)
2386 free(tbsdata);
2387
2388 return (ret);
2389 }
2390
2391 KMF_RETURN
DerEncodeSignedCsr(KMF_CSR_DATA * signed_csr_ptr,KMF_DATA * encodedcsr)2392 DerEncodeSignedCsr(KMF_CSR_DATA *signed_csr_ptr,
2393 KMF_DATA *encodedcsr)
2394 {
2395 KMF_RETURN ret = KMF_OK;
2396 KMF_TBS_CSR *tbscsr = NULL;
2397 KMF_X509_SIGNATURE *signature = NULL;
2398 BerElement *asn1 = NULL;
2399 BerValue *tbsdata = NULL;
2400
2401 if (signed_csr_ptr == NULL)
2402 return (KMF_ERR_BAD_PARAMETER);
2403
2404 tbscsr = &signed_csr_ptr->csr;
2405 signature = &signed_csr_ptr->signature;
2406
2407 asn1 = kmfder_alloc();
2408 if (asn1 == NULL)
2409 return (KMF_ERR_MEMORY);
2410
2411 /* Start outer CSR SEQUENCE */
2412 if (kmfber_printf(asn1, "{") == -1) {
2413 ret = KMF_ERR_BAD_CERT_FORMAT;
2414 goto cleanup;
2415 }
2416
2417 ret = encode_tbs_csr(asn1, tbscsr);
2418
2419 /* Add the Algorithm & Signature Sequence */
2420 if ((ret = encode_algoid(asn1,
2421 &signature->algorithmIdentifier, FALSE)) != KMF_OK)
2422 goto cleanup;
2423
2424 if (signature->encrypted.Length > 0) {
2425 if (kmfber_printf(asn1, "B", signature->encrypted.Data,
2426 signature->encrypted.Length * 8) == -1) {
2427 ret = KMF_ERR_BAD_CERT_FORMAT;
2428 goto cleanup;
2429 }
2430 }
2431
2432 if (kmfber_printf(asn1, "}") == -1) {
2433 ret = KMF_ERR_BAD_CERT_FORMAT;
2434 goto cleanup;
2435 }
2436
2437 if (kmfber_flatten(asn1, &tbsdata) == -1) {
2438 ret = KMF_ERR_MEMORY;
2439 goto cleanup;
2440 }
2441
2442 encodedcsr->Data = (uchar_t *)tbsdata->bv_val;
2443 encodedcsr->Length = tbsdata->bv_len;
2444
2445 cleanup:
2446 if (ret != KMF_OK) {
2447 free_data(encodedcsr);
2448 }
2449
2450 if (tbsdata)
2451 free(tbsdata);
2452
2453 if (asn1)
2454 kmfber_free(asn1, 1);
2455 return (ret);
2456 }
2457
2458 static KMF_RETURN
ber_copy_data(KMF_DATA * dst,KMF_DATA * src)2459 ber_copy_data(KMF_DATA *dst, KMF_DATA *src)
2460 {
2461 KMF_RETURN ret = KMF_OK;
2462
2463 if (dst == NULL || src == NULL)
2464 return (KMF_ERR_BAD_PARAMETER);
2465
2466 dst->Data = malloc(src->Length);
2467 if (dst->Data == NULL)
2468 return (KMF_ERR_MEMORY);
2469
2470 dst->Length = src->Length;
2471 (void) memcpy(dst->Data, src->Data, src->Length);
2472
2473 return (ret);
2474 }
2475
2476 KMF_RETURN
ExtractSPKIData(const KMF_X509_SPKI * pKey,KMF_ALGORITHM_INDEX AlgorithmId,KMF_DATA * pKeyParts,uint32_t * uNumKeyParts)2477 ExtractSPKIData(
2478 const KMF_X509_SPKI *pKey,
2479 KMF_ALGORITHM_INDEX AlgorithmId,
2480 KMF_DATA *pKeyParts,
2481 uint32_t *uNumKeyParts)
2482 {
2483 KMF_RETURN ret = KMF_OK;
2484 BerElement *asn1 = NULL;
2485 BerValue *P, *Q, *G, *Mod, *Exp, *PubKey;
2486 BerValue PubKeyParams, PubKeyData;
2487
2488 if (pKeyParts == NULL || uNumKeyParts == NULL || pKey == NULL)
2489 return (KMF_ERR_BAD_PARAMETER);
2490
2491 switch (AlgorithmId) {
2492 case KMF_ALGID_DSA:
2493 case KMF_ALGID_SHA1WithDSA:
2494 *uNumKeyParts = 0;
2495 /* Get the parameters from the algorithm definition */
2496 PubKeyParams.bv_val =
2497 (char *)pKey->algorithm.parameters.Data;
2498 PubKeyParams.bv_len = pKey->algorithm.parameters.Length;
2499 if ((asn1 = kmfder_init(&PubKeyParams)) == NULL)
2500 return (KMF_ERR_MEMORY);
2501
2502 if (kmfber_scanf(asn1, "{III}", &P, &Q, &G) == -1) {
2503 kmfber_free(asn1, 1);
2504 return (KMF_ERR_BAD_KEY_FORMAT);
2505 }
2506 pKeyParts[KMF_DSA_PRIME].Data = (uchar_t *)P->bv_val;
2507 pKeyParts[KMF_DSA_PRIME].Length = P->bv_len;
2508 pKeyParts[KMF_DSA_SUB_PRIME].Data =
2509 (uchar_t *)Q->bv_val;
2510 pKeyParts[KMF_DSA_SUB_PRIME].Length = Q->bv_len;
2511 pKeyParts[KMF_DSA_BASE].Data = (uchar_t *)G->bv_val;
2512 pKeyParts[KMF_DSA_BASE].Length = G->bv_len;
2513
2514 free(P);
2515 free(Q);
2516 free(G);
2517 kmfber_free(asn1, 1);
2518
2519 /* Get the PubKey data */
2520 PubKeyData.bv_val = (char *)pKey->subjectPublicKey.Data;
2521 PubKeyData.bv_len = pKey->subjectPublicKey.Length;
2522 if ((asn1 = kmfder_init(&PubKeyData)) == NULL) {
2523 ret = KMF_ERR_MEMORY;
2524 goto cleanup;
2525 }
2526 PubKey = NULL;
2527 if (kmfber_scanf(asn1, "I", &PubKey) == -1) {
2528 ret = KMF_ERR_BAD_KEY_FORMAT;
2529 goto cleanup;
2530 }
2531 pKeyParts[KMF_DSA_PUBLIC_VALUE].Data =
2532 (uchar_t *)PubKey->bv_val;
2533 pKeyParts[KMF_DSA_PUBLIC_VALUE].Length = PubKey->bv_len;
2534
2535 free(PubKey);
2536
2537 *uNumKeyParts = KMF_NUMBER_DSA_PUBLIC_KEY_PARTS;
2538 break;
2539 case KMF_ALGID_SHA1WithECDSA:
2540 case KMF_ALGID_ECDSA:
2541 (void) ber_copy_data(&pKeyParts[KMF_ECDSA_PARAMS],
2542 (KMF_DATA *)&pKey->algorithm.parameters);
2543
2544 (void) ber_copy_data(&pKeyParts[KMF_ECDSA_POINT],
2545 (KMF_DATA *)&pKey->subjectPublicKey);
2546
2547 *uNumKeyParts = 2;
2548 break;
2549
2550 case KMF_ALGID_RSA:
2551 case KMF_ALGID_MD2WithRSA:
2552 case KMF_ALGID_MD5WithRSA:
2553 case KMF_ALGID_SHA1WithRSA:
2554 *uNumKeyParts = 0;
2555 PubKeyData.bv_val = (char *)pKey->subjectPublicKey.Data;
2556 PubKeyData.bv_len = pKey->subjectPublicKey.Length;
2557 if ((asn1 = kmfder_init(&PubKeyData)) == NULL) {
2558 ret = KMF_ERR_MEMORY;
2559 goto cleanup;
2560 }
2561 if (kmfber_scanf(asn1, "{II}", &Mod, &Exp) == -1) {
2562 ret = KMF_ERR_BAD_KEY_FORMAT;
2563 goto cleanup;
2564 }
2565 pKeyParts[KMF_RSA_MODULUS].Data =
2566 (uchar_t *)Mod->bv_val;
2567 pKeyParts[KMF_RSA_MODULUS].Length = Mod->bv_len;
2568 pKeyParts[KMF_RSA_PUBLIC_EXPONENT].Data =
2569 (uchar_t *)Exp->bv_val;
2570 pKeyParts[KMF_RSA_PUBLIC_EXPONENT].Length = Exp->bv_len;
2571 *uNumKeyParts = KMF_NUMBER_RSA_PUBLIC_KEY_PARTS;
2572
2573 free(Mod);
2574 free(Exp);
2575 break;
2576 default:
2577 return (KMF_ERR_BAD_PARAMETER);
2578 }
2579 cleanup:
2580 if (ret != KMF_OK) {
2581 int i;
2582 for (i = 0; i < *uNumKeyParts; i++)
2583 free_data(&pKeyParts[i]);
2584 }
2585 if (asn1 != NULL) {
2586 kmfber_free(asn1, 1);
2587 }
2588
2589 return (ret);
2590 }
2591