13089Swyllys /* 23433Shaimay * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 33089Swyllys * Use is subject to license terms. 43433Shaimay */ 53433Shaimay /* 63089Swyllys * Copyright (c) 1995-1999 Intel Corporation. All rights reserved. 73089Swyllys */ 83089Swyllys 93089Swyllys #pragma ident "%Z%%M% %I% %E% SMI" 103089Swyllys 113089Swyllys #include <strings.h> 123089Swyllys #include <kmftypes.h> 133089Swyllys #include <ber_der.h> 143089Swyllys #include <kmfapi.h> 153089Swyllys #include <kmfapiP.h> 163089Swyllys 173089Swyllys #include <stdio.h> 183089Swyllys 193089Swyllys #define DSA_RAW_SIG_LEN 40 203089Swyllys 213089Swyllys static uint8_t OID_ExtensionRequest[] = { OID_PKCS_9, 14 }; 223089Swyllys const KMF_OID extension_request_oid = {OID_PKCS_9_LENGTH + 1, 233089Swyllys OID_ExtensionRequest}; 243089Swyllys 253089Swyllys static KMF_RETURN 263089Swyllys encode_algoid(BerElement *asn1, KMF_X509_ALGORITHM_IDENTIFIER *algoid) 273089Swyllys { 283089Swyllys KMF_RETURN ret = KMF_OK; 293089Swyllys 303089Swyllys if (kmfber_printf(asn1, "{D", &algoid->algorithm) == -1) { 313089Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 323089Swyllys } 333089Swyllys if (algoid->parameters.Data == NULL || 343089Swyllys algoid->parameters.Length == 0) { 353089Swyllys if (kmfber_printf(asn1, "n}") == -1) 363089Swyllys return (KMF_ERR_BAD_CERT_FORMAT); 373089Swyllys } else { 383089Swyllys /* 393089Swyllys * The algorithm data can be anything, so we just write it 403089Swyllys * straight into the buffer. It is already DER encoded. 413089Swyllys */ 423089Swyllys (void) kmfber_write(asn1, (char *)algoid->parameters.Data, 433089Swyllys algoid->parameters.Length, 0); 443089Swyllys if (kmfber_printf(asn1, "}") == -1) { 453089Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 463089Swyllys } 473089Swyllys } 483089Swyllys 493089Swyllys return (ret); 503089Swyllys } 513089Swyllys 523089Swyllys static void 533089Swyllys free_data(KMF_DATA *data) 543089Swyllys { 553089Swyllys if (data == NULL || data->Data == NULL) 563089Swyllys return; 573089Swyllys 583089Swyllys free(data->Data); 593089Swyllys data->Data = NULL; 603089Swyllys data->Length = 0; 613089Swyllys } 623089Swyllys 633089Swyllys static void 643089Swyllys free_algoid(KMF_X509_ALGORITHM_IDENTIFIER *algoid) 653089Swyllys { 663089Swyllys free_data(&algoid->algorithm); 673089Swyllys free_data(&algoid->parameters); 683089Swyllys } 693089Swyllys 703089Swyllys static void 713089Swyllys free_decoded_spki(KMF_X509_SPKI *spki) 723089Swyllys { 733089Swyllys if (spki != NULL) { 743089Swyllys free_algoid(&spki->algorithm); 753089Swyllys free_data(&spki->subjectPublicKey); 763089Swyllys } 773089Swyllys } 783089Swyllys 793089Swyllys static void 803089Swyllys free_rdn_data(KMF_X509_NAME *name) 813089Swyllys { 823089Swyllys KMF_X509_RDN *newrdn = NULL; 833089Swyllys KMF_X509_TYPE_VALUE_PAIR *av = NULL; 843089Swyllys int i, j; 853089Swyllys 863089Swyllys if (name && name->numberOfRDNs) { 873089Swyllys for (i = 0; i < name->numberOfRDNs; i++) { 883089Swyllys newrdn = &name->RelativeDistinguishedName[i]; 893089Swyllys for (j = 0; j < newrdn->numberOfPairs; j++) { 903089Swyllys av = &newrdn->AttributeTypeAndValue[j]; 913089Swyllys free_data(&av->type); 923089Swyllys free_data(&av->value); 933089Swyllys } 943089Swyllys free(newrdn->AttributeTypeAndValue); 953089Swyllys } 963089Swyllys free(name->RelativeDistinguishedName); 973089Swyllys name->numberOfRDNs = 0; 983089Swyllys name->RelativeDistinguishedName = NULL; 993089Swyllys } 1003089Swyllys } 1013089Swyllys 1023089Swyllys static void 1033089Swyllys free_validity(KMF_X509_VALIDITY *validity) 1043089Swyllys { 1053089Swyllys free_data(&validity->notBefore.time); 1063089Swyllys free_data(&validity->notAfter.time); 1073089Swyllys } 1083089Swyllys 1093089Swyllys static void 1103089Swyllys free_one_extension(KMF_X509_EXTENSION *exptr) 1113089Swyllys { 1123089Swyllys free_data(&exptr->extnId); 1133089Swyllys free_data(&exptr->BERvalue); 1143089Swyllys 1153089Swyllys if (exptr->value.tagAndValue) { 1163089Swyllys free_data(&exptr->value.tagAndValue->value); 1173089Swyllys free(exptr->value.tagAndValue); 1183089Swyllys } 1193089Swyllys } 1203089Swyllys 1213089Swyllys static void 1223089Swyllys free_extensions(KMF_X509_EXTENSIONS *extns) 1233089Swyllys { 1243089Swyllys int i; 1253089Swyllys KMF_X509_EXTENSION *exptr; 1263089Swyllys 1273089Swyllys if (extns && extns->numberOfExtensions > 0) { 1283089Swyllys for (i = 0; i < extns->numberOfExtensions; i++) { 1293089Swyllys exptr = &extns->extensions[i]; 1303089Swyllys free_one_extension(exptr); 1313089Swyllys } 1323089Swyllys free(extns->extensions); 1333089Swyllys extns->numberOfExtensions = 0; 1343089Swyllys extns->extensions = NULL; 1353089Swyllys } 1363089Swyllys } 1373089Swyllys 1383089Swyllys static void 1393089Swyllys free_tbscsr(KMF_TBS_CSR *tbscsr) 1403089Swyllys { 1413089Swyllys if (tbscsr) { 1423089Swyllys free_data(&tbscsr->version); 1433089Swyllys 1443089Swyllys free_rdn_data(&tbscsr->subject); 1453089Swyllys 1463089Swyllys free_decoded_spki(&tbscsr->subjectPublicKeyInfo); 1473089Swyllys 1483089Swyllys free_extensions(&tbscsr->extensions); 1493089Swyllys } 1503089Swyllys } 1513089Swyllys 1523089Swyllys 1533089Swyllys static void 1543089Swyllys free_bigint(KMF_BIGINT *bn) 1553089Swyllys { 1563089Swyllys if (bn != NULL && bn->val != NULL) { 1573089Swyllys free(bn->val); 1583089Swyllys bn->val = NULL; 1593089Swyllys bn->len = 0; 1603089Swyllys } 1613089Swyllys } 1623089Swyllys 1633089Swyllys static void 1643089Swyllys free_tbscert(KMF_X509_TBS_CERT *tbscert) 1653089Swyllys { 1663089Swyllys if (tbscert) { 1673089Swyllys free_data(&tbscert->version); 1683089Swyllys free_bigint(&tbscert->serialNumber); 1693089Swyllys free_algoid(&tbscert->signature); 1703089Swyllys 1713089Swyllys free_rdn_data(&tbscert->issuer); 1723089Swyllys free_rdn_data(&tbscert->subject); 1733089Swyllys 1743089Swyllys free_validity(&tbscert->validity); 1753089Swyllys 1763089Swyllys free_data(&tbscert->issuerUniqueIdentifier); 1773089Swyllys free_data(&tbscert->subjectUniqueIdentifier); 1783089Swyllys free_decoded_spki(&tbscert->subjectPublicKeyInfo); 1793089Swyllys free_extensions(&tbscert->extensions); 1803089Swyllys 1813089Swyllys free_data(&tbscert->issuerUniqueIdentifier); 1823089Swyllys free_data(&tbscert->subjectUniqueIdentifier); 1833089Swyllys } 1843089Swyllys } 1853089Swyllys 1863089Swyllys static void 1873089Swyllys free_decoded_cert(KMF_X509_CERTIFICATE *certptr) 1883089Swyllys { 1893089Swyllys if (!certptr) 1903089Swyllys return; 1913089Swyllys 1923089Swyllys free_tbscert(&certptr->certificate); 1933089Swyllys 1943089Swyllys free_algoid(&certptr->signature.algorithmIdentifier); 1953089Swyllys free_data(&certptr->signature.encrypted); 1963089Swyllys } 1973089Swyllys 1983089Swyllys static KMF_RETURN 1993089Swyllys get_algoid(BerElement *asn1, KMF_X509_ALGORITHM_IDENTIFIER *algoid) 2003089Swyllys { 2013089Swyllys KMF_RETURN ret = KMF_OK; 2023089Swyllys ber_tag_t tag, newtag; 2033089Swyllys ber_len_t size; 2043089Swyllys BerValue AlgOID = {NULL, 0}; 2053089Swyllys 2063089Swyllys tag = kmfber_next_element(asn1, &size, NULL); 2073089Swyllys if (tag != BER_CONSTRUCTED_SEQUENCE) 2083089Swyllys return (KMF_ERR_BAD_CERT_FORMAT); 2093089Swyllys 2103089Swyllys if ((tag = kmfber_scanf(asn1, "{Dt", &AlgOID, &newtag)) == -1) { 2113089Swyllys return (KMF_ERR_BAD_CERT_FORMAT); 2123089Swyllys } 2133089Swyllys algoid->algorithm.Data = (uchar_t *)AlgOID.bv_val; 2143089Swyllys algoid->algorithm.Length = AlgOID.bv_len; 2153089Swyllys 2163089Swyllys if (newtag == BER_NULL) { 2173089Swyllys (void) kmfber_scanf(asn1, "n}"); 2183089Swyllys algoid->parameters.Data = NULL; 2193089Swyllys algoid->parameters.Length = 0; 2203089Swyllys } else { 2213089Swyllys /* Peek at the tag and length bytes */ 2223089Swyllys if ((kmfber_scanf(asn1, "tl", &tag, &size)) == -1) { 2233089Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 2243089Swyllys goto cleanup; 2253089Swyllys } 2263089Swyllys 2273089Swyllys /* 2283089Swyllys * We need to read the tag and the length bytes too, 2293089Swyllys * so adjust the size. 2303089Swyllys */ 2313089Swyllys size += kmfber_calc_taglen(tag) + kmfber_calc_lenlen(size); 2323089Swyllys algoid->parameters.Data = malloc(size); 2333089Swyllys if (algoid->parameters.Data == NULL) { 2343089Swyllys ret = KMF_ERR_MEMORY; 2353089Swyllys goto cleanup; 2363089Swyllys } 2373089Swyllys /* read the raw data into the Algoritm params area. */ 2383089Swyllys if (kmfber_read(asn1, (char *)algoid->parameters.Data, 2393089Swyllys size) == -1) { 2403089Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 2413089Swyllys goto cleanup; 2423089Swyllys } 2433089Swyllys algoid->parameters.Length = size; 2443089Swyllys if ((tag = kmfber_scanf(asn1, "}")) == -1) { 2453089Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 2463089Swyllys } 2473089Swyllys } 2483089Swyllys cleanup: 2493089Swyllys if (ret != KMF_OK) { 2503089Swyllys free_algoid(algoid); 2513089Swyllys } 2523089Swyllys 2533089Swyllys return (ret); 2543089Swyllys } 2553089Swyllys 2563089Swyllys static KMF_RETURN 2573089Swyllys CopyData(KMF_DATA *src, KMF_DATA *dst) 2583089Swyllys { 2593089Swyllys if (src && dst && src->Data != NULL && src->Length > 0) { 2603089Swyllys dst->Length = src->Length; 261*3991Shaimay dst->Data = malloc(dst->Length); 2623089Swyllys if (dst->Data == NULL) 2633089Swyllys return (KMF_ERR_MEMORY); 2643089Swyllys (void) memcpy(dst->Data, src->Data, src->Length); 2653089Swyllys } 2663089Swyllys return (KMF_OK); 2673089Swyllys } 2683089Swyllys 2693089Swyllys static KMF_RETURN 2703089Swyllys encode_spki(BerElement *asn1, KMF_X509_SPKI *spki) 2713089Swyllys { 2723089Swyllys KMF_RETURN ret = KMF_OK; 2733089Swyllys 2743089Swyllys if (kmfber_printf(asn1, "{") == -1) 2753089Swyllys return (KMF_ERR_BAD_CERT_FORMAT); 2763089Swyllys 2773089Swyllys if ((ret = encode_algoid(asn1, &spki->algorithm)) != KMF_OK) 2783089Swyllys return (ret); 2793089Swyllys 2803089Swyllys if (kmfber_printf(asn1, "B}", spki->subjectPublicKey.Data, 2813089Swyllys spki->subjectPublicKey.Length * 8) == -1) 2823089Swyllys return (KMF_ERR_BAD_CERT_FORMAT); 2833089Swyllys 2843089Swyllys return (ret); 2853089Swyllys } 2863089Swyllys 2873089Swyllys KMF_RETURN 2883089Swyllys DerEncodeSPKI(KMF_X509_SPKI *spki, KMF_DATA *EncodedSPKI) 2893089Swyllys { 2903089Swyllys KMF_RETURN ret = KMF_OK; 2913089Swyllys BerElement *asn1; 2923089Swyllys BerValue *result; 2933089Swyllys 2943089Swyllys if (spki == NULL || EncodedSPKI == NULL) 2953089Swyllys return (KMF_ERR_BAD_PARAMETER); 2963089Swyllys 2973089Swyllys if ((asn1 = kmfder_alloc()) == NULL) 2983089Swyllys return (KMF_ERR_MEMORY); 2993089Swyllys 3003089Swyllys if ((ret = encode_spki(asn1, spki)) != KMF_OK) { 3013089Swyllys return (ret); 3023089Swyllys } 3033089Swyllys 3043089Swyllys if (kmfber_flatten(asn1, &result) == -1) { 3053089Swyllys kmfber_free(asn1, 1); 3063089Swyllys return (KMF_ERR_ENCODING); 3073089Swyllys } 3083089Swyllys 3093089Swyllys EncodedSPKI->Data = (uchar_t *)result->bv_val; 3103089Swyllys EncodedSPKI->Length = result->bv_len; 3113089Swyllys 3123089Swyllys free(result); 3133089Swyllys kmfber_free(asn1, 1); 3143089Swyllys return (KMF_OK); 3153089Swyllys } 3163089Swyllys 3173089Swyllys static KMF_RETURN 3183089Swyllys get_spki(BerElement *asn1, KMF_X509_SPKI *spki) 3193089Swyllys { 3203089Swyllys KMF_RETURN ret = KMF_OK; 3213089Swyllys char *bitstr = NULL; 3223089Swyllys ber_len_t size; 3233089Swyllys 3243089Swyllys if (kmfber_scanf(asn1, "{") == -1) 3253089Swyllys return (KMF_ERR_BAD_CERT_FORMAT); 3263089Swyllys 3273089Swyllys if ((ret = get_algoid(asn1, &spki->algorithm)) != KMF_OK) 3283089Swyllys return (ret); 3293089Swyllys 3303089Swyllys if (kmfber_scanf(asn1, "B}", &bitstr, &size) == BER_BIT_STRING) { 3313089Swyllys spki->subjectPublicKey.Data = (uchar_t *)bitstr; 3323089Swyllys spki->subjectPublicKey.Length = size / 8; 3333089Swyllys } else { 3343089Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 3353089Swyllys goto cleanup; 3363089Swyllys } 3373089Swyllys cleanup: 3383089Swyllys if (ret != KMF_OK) { 3393089Swyllys if (bitstr != NULL) 3403089Swyllys free(bitstr); 3413089Swyllys spki->subjectPublicKey.Data = NULL; 3423089Swyllys spki->subjectPublicKey.Length = 0; 3433089Swyllys 3443089Swyllys free_algoid(&spki->algorithm); 3453089Swyllys } 3463089Swyllys return (ret); 3473089Swyllys } 3483089Swyllys 3493089Swyllys KMF_RETURN 3503089Swyllys DerEncodeDSASignature(KMF_DATA *rawdata, KMF_DATA *signature) 3513089Swyllys { 3523089Swyllys BerElement *asn1; 3533089Swyllys BerValue *buf; 3543089Swyllys int n; 3553089Swyllys 3563089Swyllys if (rawdata == NULL || signature == NULL) 3573089Swyllys return (KMF_ERR_BAD_PARAMETER); 3583089Swyllys 3593089Swyllys if (rawdata->Data == NULL || rawdata->Length != DSA_RAW_SIG_LEN) 3603089Swyllys return (KMF_ERR_BAD_PARAMETER); 3613089Swyllys 3623089Swyllys asn1 = kmfder_alloc(); 3633089Swyllys if (asn1 == NULL) 3643089Swyllys return (KMF_ERR_MEMORY); 3653089Swyllys 3663089Swyllys /* 3673089Swyllys * The DSA signature is the concatenation of 2 SHA-1 hashed 3683089Swyllys * bignum values. 3693089Swyllys */ 3703089Swyllys n = DSA_RAW_SIG_LEN/2; 3713089Swyllys if (kmfber_printf(asn1, "{II}", 3723089Swyllys rawdata->Data, n, 3733089Swyllys &rawdata->Data[n], n) == -1) { 3743089Swyllys kmfber_free(asn1, 1); 3753089Swyllys return (KMF_ERR_MEMORY); 3763089Swyllys } 3773089Swyllys 3783089Swyllys if (kmfber_flatten(asn1, &buf) == -1) { 3793089Swyllys kmfber_free(asn1, 1); 3803089Swyllys return (KMF_ERR_ENCODING); 3813089Swyllys } 3823089Swyllys 3833089Swyllys signature->Data = (uchar_t *)buf->bv_val; 3843089Swyllys signature->Length = buf->bv_len; 3853089Swyllys 3863089Swyllys kmfber_free(asn1, 1); 3873089Swyllys free(buf); 3883089Swyllys 3893089Swyllys return (KMF_OK); 3903089Swyllys } 3913089Swyllys 3923089Swyllys KMF_RETURN 3933089Swyllys DerDecodeDSASignature(KMF_DATA *encoded, KMF_DATA *signature) 3943089Swyllys { 3953089Swyllys KMF_RETURN ret = KMF_OK; 3963089Swyllys BerElement *asn1 = NULL; 3973089Swyllys BerValue buf, *R = NULL, *S = NULL; 3983089Swyllys 3993089Swyllys buf.bv_val = (char *)encoded->Data; 4003089Swyllys buf.bv_len = encoded->Length; 4013089Swyllys 4023089Swyllys if (encoded == NULL || encoded->Data == NULL || 4033089Swyllys signature == NULL) 4043089Swyllys return (KMF_ERR_BAD_PARAMETER); 4053089Swyllys 4063089Swyllys signature->Data = NULL; 4073089Swyllys signature->Length = 0; 4083089Swyllys 4093089Swyllys if ((asn1 = kmfder_init(&buf)) == NULL) 4103089Swyllys return (KMF_ERR_MEMORY); 4113089Swyllys 4123089Swyllys if (kmfber_scanf(asn1, "{II}", &R, &S) == -1) { 4133089Swyllys ret = KMF_ERR_BAD_PARAMETER; 4143089Swyllys goto cleanup; 4153089Swyllys } 4163089Swyllys signature->Length = R->bv_len + S->bv_len; 4173089Swyllys signature->Data = malloc(signature->Length); 4183089Swyllys if (signature->Data == NULL) { 4193089Swyllys ret = KMF_ERR_MEMORY; 4203089Swyllys goto cleanup; 4213089Swyllys } 4223089Swyllys (void) memcpy(signature->Data, R->bv_val, R->bv_len); 4233089Swyllys (void) memcpy(&signature->Data[R->bv_len], S->bv_val, S->bv_len); 4243089Swyllys 4253089Swyllys cleanup: 4263089Swyllys if (R && R->bv_val) 4273089Swyllys free(R->bv_val); 4283089Swyllys if (S && S->bv_val) 4293089Swyllys free(S->bv_val); 4303089Swyllys 4313089Swyllys if (S) free(S); 4323089Swyllys if (R) free(R); 4333089Swyllys 4343089Swyllys if (asn1) kmfber_free(asn1, 1); 4353089Swyllys 4363089Swyllys return (ret); 4373089Swyllys } 4383089Swyllys 4393089Swyllys KMF_RETURN 4403089Swyllys DerDecodeSPKI(KMF_DATA *EncodedSPKI, KMF_X509_SPKI *spki) 4413089Swyllys { 4423089Swyllys KMF_RETURN ret = KMF_OK; 4433089Swyllys BerElement *asn1; 4443089Swyllys BerValue bv; 4453089Swyllys 4463089Swyllys if (EncodedSPKI == NULL || EncodedSPKI->Data == NULL || 4473089Swyllys spki == NULL) 4483089Swyllys return (KMF_ERR_BAD_PARAMETER); 4493089Swyllys 4503089Swyllys (void) memset(spki, 0, sizeof (KMF_X509_SPKI)); 4513089Swyllys 4523089Swyllys bv.bv_val = (char *)EncodedSPKI->Data; 4533089Swyllys bv.bv_len = EncodedSPKI->Length; 4543089Swyllys 4553089Swyllys if ((asn1 = kmfder_init(&bv)) == NULL) 4563089Swyllys return (KMF_ERR_MEMORY); 4573089Swyllys 4583089Swyllys ret = get_spki(asn1, spki); 4593089Swyllys 4603089Swyllys cleanup: 4613089Swyllys if (ret != KMF_OK) { 4623089Swyllys free_decoded_spki(spki); 4633089Swyllys } 4643089Swyllys kmfber_free(asn1, 1); 4653089Swyllys 4663089Swyllys return (ret); 4673089Swyllys } 4683089Swyllys 4693089Swyllys KMF_RETURN 4703089Swyllys CopySPKI(KMF_X509_SPKI *src, 4713089Swyllys KMF_X509_SPKI **dest) 4723089Swyllys { 4733089Swyllys KMF_RETURN ret = KMF_OK; 4743089Swyllys KMF_X509_SPKI *newspki; 4753089Swyllys 4763089Swyllys *dest = NULL; 4773089Swyllys 4783089Swyllys newspki = malloc(sizeof (KMF_X509_SPKI)); 4793089Swyllys if (newspki == NULL) 4803089Swyllys return (KMF_ERR_MEMORY); 4813089Swyllys (void) memset(newspki, 0, sizeof (KMF_X509_SPKI)); 4823089Swyllys 4833089Swyllys ret = CopyData(&src->algorithm.algorithm, 4843089Swyllys &newspki->algorithm.algorithm); 4853089Swyllys if (ret != KMF_OK) 4863089Swyllys goto cleanup; 4873089Swyllys 4883089Swyllys ret = CopyData(&src->algorithm.parameters, 4893089Swyllys &newspki->algorithm.parameters); 4903089Swyllys if (ret != KMF_OK) 4913089Swyllys goto cleanup; 4923089Swyllys 4933089Swyllys ret = CopyData(&src->subjectPublicKey, 4943089Swyllys &newspki->subjectPublicKey); 4953089Swyllys if (ret != KMF_OK) 4963089Swyllys goto cleanup; 4973089Swyllys 4983089Swyllys *dest = newspki; 4993089Swyllys cleanup: 5003089Swyllys if (ret != KMF_OK) { 5013089Swyllys if (newspki) 5023089Swyllys free_decoded_spki(newspki); 5033089Swyllys } 5043089Swyllys return (ret); 5053089Swyllys } 5063089Swyllys 5073089Swyllys static KMF_RETURN 5083089Swyllys encode_validity(BerElement *asn1, KMF_X509_VALIDITY *validity) 5093089Swyllys { 5103089Swyllys int ret; 5113089Swyllys 5123089Swyllys ret = kmfber_printf(asn1, "{tsts}", 5133089Swyllys validity->notBefore.timeType, 5143089Swyllys validity->notBefore.time.Data, 5153089Swyllys validity->notAfter.timeType, 5163089Swyllys validity->notAfter.time.Data); 5173089Swyllys 5183089Swyllys if (ret == -1) 5193089Swyllys return (KMF_ERR_BAD_CERT_FORMAT); 5203089Swyllys 5213089Swyllys return (KMF_OK); 5223089Swyllys } 5233089Swyllys 5243089Swyllys static KMF_RETURN 5253089Swyllys get_validity(BerElement *asn1, KMF_X509_VALIDITY *validity) 5263089Swyllys { 5273089Swyllys KMF_RETURN ret = KMF_OK; 5283089Swyllys int tag; 5293089Swyllys int t1, t2; 5303089Swyllys ber_len_t size; 5313089Swyllys char *t1str, *t2str; 5323089Swyllys 5333089Swyllys (void) memset(validity, 0, sizeof (KMF_X509_VALIDITY)); 5343089Swyllys 5353089Swyllys tag = kmfber_next_element(asn1, &size, NULL); 5363089Swyllys if (tag != BER_CONSTRUCTED_SEQUENCE) { 5373089Swyllys return (KMF_ERR_BAD_CERT_FORMAT); 5383089Swyllys } 5393089Swyllys 5403089Swyllys if (kmfber_scanf(asn1, "{tata}", &t1, &t1str, &t2, &t2str) == -1) { 5413089Swyllys return (KMF_ERR_BAD_CERT_FORMAT); 5423089Swyllys } 5433089Swyllys 5443089Swyllys validity->notBefore.timeType = t1; 5453089Swyllys validity->notBefore.time.Data = (uchar_t *)t1str; 5463089Swyllys validity->notBefore.time.Length = strlen(t1str); 5473089Swyllys 5483089Swyllys validity->notAfter.timeType = t2; 5493089Swyllys validity->notAfter.time.Data = (uchar_t *)t2str; 5503089Swyllys validity->notAfter.time.Length = strlen(t2str); 5513089Swyllys 5523089Swyllys return (ret); 5533089Swyllys } 5543089Swyllys 5553089Swyllys KMF_RETURN 5563089Swyllys AddRDN(KMF_X509_NAME *name, KMF_X509_RDN *newrdn) 5573089Swyllys { 5583089Swyllys KMF_RETURN ret = KMF_OK; 5593089Swyllys KMF_X509_RDN *rdnslot = NULL; 5603089Swyllys 5613089Swyllys /* Add new RDN record to existing list */ 5623089Swyllys name->numberOfRDNs++; 5633089Swyllys name->RelativeDistinguishedName = 5643089Swyllys realloc(name->RelativeDistinguishedName, 5653089Swyllys name->numberOfRDNs * sizeof (KMF_X509_RDN)); 5663089Swyllys 5673089Swyllys if (name->RelativeDistinguishedName == NULL) { 5683089Swyllys ret = KMF_ERR_MEMORY; 5693089Swyllys goto cleanup; 5703089Swyllys } 5713089Swyllys rdnslot = &name->RelativeDistinguishedName[name->numberOfRDNs-1]; 5723089Swyllys 5733089Swyllys if (newrdn) { 5743089Swyllys (void) memcpy(rdnslot, newrdn, sizeof (KMF_X509_RDN)); 5753089Swyllys } else { 5763089Swyllys rdnslot->numberOfPairs = 0; 5773089Swyllys rdnslot->AttributeTypeAndValue = NULL; 5783089Swyllys } 5793089Swyllys 5803089Swyllys cleanup: 5813089Swyllys /* No cleanup needed here */ 5823089Swyllys return (ret); 5833089Swyllys } 5843089Swyllys 5853089Swyllys static KMF_RETURN 5863089Swyllys encode_rdn(BerElement *asn1, KMF_X509_NAME *name) 5873089Swyllys { 5883089Swyllys KMF_RETURN ret = KMF_OK; 5893089Swyllys KMF_X509_TYPE_VALUE_PAIR *attrtvpair = NULL; 5903089Swyllys int i; 5913089Swyllys KMF_X509_RDN *rdn; 5923089Swyllys 5933089Swyllys if (kmfber_printf(asn1, "{") == -1) { 5943089Swyllys ret = KMF_ERR_MEMORY; 5953089Swyllys goto cleanup; 5963089Swyllys } 5973089Swyllys 5983089Swyllys for (i = 0; i < name->numberOfRDNs; i++) { 5993089Swyllys if (kmfber_printf(asn1, "[") == -1) { 6003089Swyllys ret = KMF_ERR_MEMORY; 6013089Swyllys goto cleanup; 6023089Swyllys } 6033089Swyllys rdn = &name->RelativeDistinguishedName[i]; 6043089Swyllys attrtvpair = rdn->AttributeTypeAndValue; 6053089Swyllys 6063089Swyllys if (rdn->numberOfPairs > 0) { 6073089Swyllys if (kmfber_printf(asn1, "{Dto}", 6083089Swyllys &attrtvpair->type, 6093089Swyllys attrtvpair->valueType, 6103089Swyllys attrtvpair->value.Data, 6113089Swyllys attrtvpair->value.Length) == -1) { 6123089Swyllys ret = KMF_ERR_MEMORY; 6133089Swyllys goto cleanup; 6143089Swyllys } 6153089Swyllys } 6163089Swyllys if (kmfber_printf(asn1, "]") == -1) { 6173089Swyllys ret = KMF_ERR_MEMORY; 6183089Swyllys goto cleanup; 6193089Swyllys } 6203089Swyllys } 6213089Swyllys 6223089Swyllys if (kmfber_printf(asn1, "}") == -1) { 6233089Swyllys ret = KMF_ERR_MEMORY; 6243089Swyllys goto cleanup; 6253089Swyllys } 6263089Swyllys 6273089Swyllys cleanup: 6283089Swyllys /* No cleanup needed here */ 6293089Swyllys 6303089Swyllys return (ret); 6313089Swyllys } 6323089Swyllys 6333089Swyllys 6343089Swyllys KMF_RETURN 6353089Swyllys CopyRDN(KMF_X509_NAME *srcname, KMF_X509_NAME **destname) 6363089Swyllys { 6373089Swyllys KMF_RETURN ret = KMF_OK; 6383089Swyllys KMF_X509_NAME *newname = NULL; 6393089Swyllys KMF_X509_RDN *rdn, *dstrdn; 6403089Swyllys KMF_X509_TYPE_VALUE_PAIR *av = NULL; 6413089Swyllys KMF_X509_TYPE_VALUE_PAIR *srcav = NULL; 6423089Swyllys KMF_X509_TYPE_VALUE_PAIR *dstav = NULL; 6433089Swyllys int i, j; 6443089Swyllys 6453089Swyllys newname = malloc(sizeof (KMF_X509_NAME)); 6463089Swyllys if (newname == NULL) 6473089Swyllys return (KMF_ERR_MEMORY); 6483089Swyllys (void) memset(newname, 0, sizeof (KMF_X509_NAME)); 6493089Swyllys 6503089Swyllys newname->numberOfRDNs = srcname->numberOfRDNs; 6513089Swyllys newname->RelativeDistinguishedName = malloc(newname->numberOfRDNs * 6523089Swyllys sizeof (KMF_X509_RDN)); 6533089Swyllys if (newname->RelativeDistinguishedName == NULL) { 6543089Swyllys free(newname); 6553089Swyllys return (KMF_ERR_MEMORY); 6563089Swyllys } 6573089Swyllys /* Copy each RDN in the list */ 6583089Swyllys for (i = 0; i < newname->numberOfRDNs; i++) { 6593089Swyllys rdn = &srcname->RelativeDistinguishedName[i]; 6603089Swyllys 6613089Swyllys dstrdn = &newname->RelativeDistinguishedName[i]; 6623089Swyllys (void) memset(dstrdn, 0, sizeof (KMF_X509_RDN)); 6633089Swyllys 6643089Swyllys dstrdn->numberOfPairs = rdn->numberOfPairs; 6653089Swyllys if (dstrdn->numberOfPairs > 0) { 6663089Swyllys av = malloc(dstrdn->numberOfPairs * 6673089Swyllys sizeof (KMF_X509_TYPE_VALUE_PAIR)); 6683089Swyllys if (av == NULL) { 6693089Swyllys ret = KMF_ERR_MEMORY; 6703089Swyllys goto cleanup; 6713089Swyllys } 6723089Swyllys (void) memset(av, 0, dstrdn->numberOfPairs * 6733089Swyllys sizeof (KMF_X509_TYPE_VALUE_PAIR)); 6743089Swyllys 6753089Swyllys dstrdn->AttributeTypeAndValue = av; 6763089Swyllys if (av == NULL) { 6773089Swyllys ret = KMF_ERR_MEMORY; 6783089Swyllys goto cleanup; 6793089Swyllys } 6803089Swyllys /* Copy each A/V pair in the list */ 6813089Swyllys for (j = 0; j < dstrdn->numberOfPairs; j++) { 6823089Swyllys srcav = &rdn->AttributeTypeAndValue[j]; 6833089Swyllys dstav = &dstrdn->AttributeTypeAndValue[j]; 6843089Swyllys if ((ret = CopyData(&srcav->type, 6853089Swyllys &dstav->type)) != KMF_OK) 6863089Swyllys goto cleanup; 6873089Swyllys dstav->valueType = srcav->valueType; 6883089Swyllys if ((ret = CopyData(&srcav->value, 6893089Swyllys &dstav->value)) != KMF_OK) 6903089Swyllys goto cleanup; 6913089Swyllys } 6923089Swyllys } else { 6933089Swyllys dstrdn->AttributeTypeAndValue = NULL; 6943089Swyllys } 6953089Swyllys } 6963089Swyllys *destname = newname; 6973089Swyllys 6983089Swyllys cleanup: 6993089Swyllys if (ret != KMF_OK) { 7003089Swyllys if (newname) 7013089Swyllys free_rdn_data(newname); 7023089Swyllys 7033089Swyllys free(newname); 7043089Swyllys *destname = NULL; 7053089Swyllys } 7063089Swyllys return (ret); 7073089Swyllys } 7083089Swyllys 7093089Swyllys #define VALID_DIRECTORYSTRING_TAG(t) ( \ 7103089Swyllys (t == BER_UTF8_STRING) || \ 7113089Swyllys (t == BER_PRINTABLE_STRING) || \ 7123089Swyllys (t == BER_IA5STRING) || \ 7133089Swyllys (t == BER_T61STRING) || \ 7143089Swyllys (t == BER_BMP_STRING) || \ 7153089Swyllys (t == BER_UNIVERSAL_STRING)) 7163089Swyllys 7173089Swyllys static KMF_RETURN 7183089Swyllys get_rdn(BerElement *asn1, KMF_X509_NAME *name) 7193089Swyllys { 7203089Swyllys KMF_RETURN ret = KMF_OK; 7213089Swyllys ber_len_t size; 7223089Swyllys char *end; 7233089Swyllys int tag; 7243089Swyllys BerValue AttrOID; 7253089Swyllys char *AttrValue = NULL; 7263089Swyllys KMF_X509_TYPE_VALUE_PAIR *newpair = NULL; 7273089Swyllys KMF_X509_RDN newrdn; 7283089Swyllys 7293089Swyllys /* 7303089Swyllys * AttributeType ::= OBJECT IDENTIFIER 7313089Swyllys * AttributeValue ::= ANY 7323089Swyllys * 7333089Swyllys * AttributeTypeAndValue ::= SEQUENCE { 7343089Swyllys * type AttributeType, 7353089Swyllys * value AttributeValue } 7363089Swyllys * 7373089Swyllys * Name ::= CHOICE { -- only one possibility for now -- 7383089Swyllys * rdnSequence RDNSequence } 7393089Swyllys * 7403089Swyllys * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName 7413089Swyllys * 7423089Swyllys * DistinguishedName ::= RDNSequence 7433089Swyllys * 7443089Swyllys * RelativeDistinguishedName ::= 7453089Swyllys * SET SIZE (1 .. MAX) OF AttributeTypeAndValue 7463089Swyllys * 7473089Swyllys */ 7483089Swyllys 7493089Swyllys name->numberOfRDNs = 0; 7503089Swyllys name->RelativeDistinguishedName = NULL; 7513089Swyllys 7523089Swyllys /* Get the beginning of the RDN Set and a ptr to the end */ 7533089Swyllys tag = kmfber_first_element(asn1, &size, &end); 7543089Swyllys if (tag != BER_CONSTRUCTED_SET) { 7553089Swyllys goto cleanup; 7563089Swyllys } 7573089Swyllys 7583089Swyllys /* Walk through the individual SET items until the "end" is reached */ 7593089Swyllys while ((tag = kmfber_next_element(asn1, &size, end)) == 7603089Swyllys BER_CONSTRUCTED_SET) { 7613089Swyllys /* Skip over the SET tag */ 7623089Swyllys if (kmfber_scanf(asn1, "T", &tag) == -1) { 7633089Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 7643089Swyllys break; 7653089Swyllys } 7663089Swyllys 7673089Swyllys /* An "empty" set member means we tack on an empty node */ 7683089Swyllys if (size == 0) { 7693089Swyllys if ((ret = AddRDN(name, NULL)) != KMF_OK) 7703089Swyllys goto cleanup; 7713089Swyllys continue; 7723089Swyllys } 7733089Swyllys 7743089Swyllys /* Attr OID and peek at the next tag and field length */ 7753089Swyllys if (kmfber_scanf(asn1, "{Dtl", &AttrOID, &tag, &size) == -1) { 7763089Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 7773089Swyllys break; 7783089Swyllys } 7793089Swyllys 7803089Swyllys if (!(VALID_DIRECTORYSTRING_TAG(tag))) { 7813089Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 7823089Swyllys break; 7833089Swyllys } 7843089Swyllys 7853089Swyllys if (kmfber_scanf(asn1, "a}]", &AttrValue) == -1) { 7863089Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 7873089Swyllys break; 7883089Swyllys } 7893089Swyllys 7903089Swyllys /* Allocate a new name/value pair record */ 7913089Swyllys newpair = malloc(sizeof (KMF_X509_TYPE_VALUE_PAIR)); 7923089Swyllys if (newpair == NULL) { 7933089Swyllys ret = KMF_ERR_MEMORY; 7943089Swyllys break; 7953089Swyllys } 7963089Swyllys (void) memset(newpair, 0, sizeof (KMF_X509_TYPE_VALUE_PAIR)); 7973089Swyllys newpair->type.Data = (uchar_t *)AttrOID.bv_val; 7983089Swyllys newpair->type.Length = AttrOID.bv_len; 7993089Swyllys newpair->valueType = tag; /* what kind of string is it? */ 8003089Swyllys newpair->value.Data = (uchar_t *)AttrValue; 8013089Swyllys newpair->value.Length = strlen(AttrValue); 8023089Swyllys 8033089Swyllys (void) memset(&newrdn, 0, sizeof (KMF_X509_RDN)); 8043089Swyllys newrdn.numberOfPairs = 1; 8053089Swyllys newrdn.AttributeTypeAndValue = newpair; 8063089Swyllys 8073089Swyllys if ((ret = AddRDN(name, &newrdn)) != KMF_OK) 8083089Swyllys break; 8093089Swyllys } 8103089Swyllys 8113089Swyllys cleanup: 8123089Swyllys if (ret != KMF_OK) { 8133089Swyllys free_rdn_data(name); 8143089Swyllys } 8153089Swyllys return (ret); 8163089Swyllys } 8173089Swyllys 8183089Swyllys static KMF_RETURN 8193089Swyllys set_der_integer(KMF_DATA *data, int value) 8203089Swyllys { 8213089Swyllys if (data == NULL) 8223089Swyllys return (KMF_ERR_BAD_PARAMETER); 8233089Swyllys 8243089Swyllys data->Data = malloc(sizeof (int)); 8253089Swyllys if (data->Data == NULL) 8263089Swyllys return (KMF_ERR_MEMORY); 8273089Swyllys 8283089Swyllys data->Length = sizeof (int); 8293089Swyllys (void) memcpy((void *)data->Data, (const void *)&value, sizeof (int)); 8303089Swyllys 8313089Swyllys return (KMF_OK); 8323089Swyllys } 8333089Swyllys 8343089Swyllys static KMF_RETURN 8353089Swyllys set_bigint(KMF_BIGINT *data, KMF_BIGINT *bigint) 8363089Swyllys { 8373089Swyllys if (data == NULL || bigint == NULL) 8383089Swyllys return (KMF_ERR_BAD_PARAMETER); 8393089Swyllys 8403089Swyllys data->val = malloc(bigint->len); 8413089Swyllys if (data->val == NULL) 8423089Swyllys return (KMF_ERR_MEMORY); 8433089Swyllys 8443089Swyllys data->len = bigint->len; 8453089Swyllys (void) memcpy((void *)data->val, (const void *)bigint->val, 8463089Swyllys bigint->len); 8473089Swyllys 8483089Swyllys return (KMF_OK); 8493089Swyllys } 8503089Swyllys 8513089Swyllys static KMF_RETURN 8523089Swyllys encode_uniqueid(BerElement *asn1, int tag, KMF_DATA *id) 8533089Swyllys { 8543089Swyllys KMF_RETURN ret = KMF_OK; 8553089Swyllys uint32_t len; 8563089Swyllys 8573089Swyllys len = kmfber_calc_taglen(BER_BIT_STRING) + 8583089Swyllys kmfber_calc_lenlen(id->Length * 8) + id->Length; 8593089Swyllys if (kmfber_printf(asn1, "TlB", tag, len, 8603089Swyllys id->Data, id->Length * 8) == -1) 8613089Swyllys return (KMF_ERR_BAD_CERT_FORMAT); 8623089Swyllys 8633089Swyllys return (ret); 8643089Swyllys } 8653089Swyllys 8663089Swyllys static KMF_RETURN 8673089Swyllys encode_extension_list(BerElement *asn1, KMF_X509_EXTENSIONS *extns) 8683089Swyllys { 8693089Swyllys KMF_RETURN ret = KMF_OK; 8703089Swyllys int i; 8713089Swyllys 8723089Swyllys for (i = 0; i < extns->numberOfExtensions; i++) { 8733089Swyllys BerValue v; 8743089Swyllys v.bv_val = (char *)extns->extensions[i].extnId.Data; 8753089Swyllys v.bv_len = extns->extensions[i].extnId.Length; 8763089Swyllys 8773089Swyllys if (kmfber_printf(asn1, "{D", &v) == -1) { 8783089Swyllys ret = KMF_ERR_ENCODING; 8793089Swyllys goto cleanup; 8803089Swyllys } 8813089Swyllys 8823089Swyllys if (extns->extensions[i].critical) { 8833089Swyllys if (kmfber_printf(asn1, "b", 8843089Swyllys extns->extensions[i].critical) == -1) { 8853089Swyllys ret = KMF_ERR_ENCODING; 8863089Swyllys goto cleanup; 8873089Swyllys } 8883089Swyllys } 8893089Swyllys 8903089Swyllys if (kmfber_printf(asn1, "o}", 8913089Swyllys extns->extensions[i].BERvalue.Data, 8923089Swyllys extns->extensions[i].BERvalue.Length) == -1) { 8933089Swyllys ret = KMF_ERR_ENCODING; 8943089Swyllys goto cleanup; 8953089Swyllys } 8963089Swyllys } 8973089Swyllys cleanup: 8983089Swyllys return (ret); 8993089Swyllys } 9003089Swyllys 9013089Swyllys static KMF_RETURN 9023089Swyllys encode_extensions(BerElement *asn1, KMF_X509_EXTENSIONS *extns) 9033089Swyllys { 9043089Swyllys KMF_RETURN ret = KMF_OK; 9053089Swyllys BerElement *extn = NULL; 9063089Swyllys BerValue *extnvalue = NULL; 9073089Swyllys 9083089Swyllys extn = kmfder_alloc(); 9093089Swyllys if (extn == NULL) 9103089Swyllys return (KMF_ERR_MEMORY); 9113089Swyllys 9123089Swyllys if (kmfber_printf(extn, "{") == -1) { 9133089Swyllys ret = KMF_ERR_ENCODING; 9143089Swyllys goto cleanup; 9153089Swyllys } 9163089Swyllys 9173089Swyllys ret = encode_extension_list(extn, extns); 9183089Swyllys 9193089Swyllys if (kmfber_printf(extn, "}") == -1) { 9203089Swyllys ret = KMF_ERR_ENCODING; 9213089Swyllys goto cleanup; 9223089Swyllys } 9233089Swyllys 9243089Swyllys if (kmfber_flatten(extn, &extnvalue) == -1) { 9253089Swyllys ret = KMF_ERR_MEMORY; 9263089Swyllys goto cleanup; 9273089Swyllys } 9283089Swyllys 9293089Swyllys if (kmfber_printf(asn1, "Tl", 0xA3, extnvalue->bv_len) == -1) { 9303089Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 9313089Swyllys goto cleanup; 9323089Swyllys } 9333089Swyllys 9343089Swyllys if (kmfber_write(asn1, extnvalue->bv_val, extnvalue->bv_len, 0) == -1) { 9353089Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 9363089Swyllys goto cleanup; 9373089Swyllys } 9383089Swyllys 9393089Swyllys cleanup: 9403089Swyllys kmfber_free(extn, 1); 9413089Swyllys if (extnvalue != NULL) 9423089Swyllys kmfber_bvfree(extnvalue); 9433089Swyllys 9443089Swyllys return (ret); 9453089Swyllys } 9463089Swyllys 9473089Swyllys static KMF_RETURN 9483089Swyllys get_one_extension(BerElement *asn1, KMF_X509_EXTENSION **retex, char *end) 9493089Swyllys { 9503089Swyllys KMF_RETURN ret = KMF_OK; 9513089Swyllys ber_len_t size; 9523089Swyllys int critical, tag; 9533089Swyllys KMF_X509_EXTENSION *ex = NULL; 9543089Swyllys BerValue extOID; 9553089Swyllys BerValue extValue; 9563089Swyllys BerElement *extnber = NULL; 9573089Swyllys 9583089Swyllys if (kmfber_scanf(asn1, "T", &tag) == -1) { 9593089Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 9603089Swyllys goto cleanup; 9613089Swyllys } 9623089Swyllys 9633089Swyllys tag = kmfber_next_element(asn1, &size, end); 9643089Swyllys if (tag != BER_OBJECT_IDENTIFIER) { 9653089Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 9663089Swyllys goto cleanup; 9673089Swyllys } 9683089Swyllys if (kmfber_scanf(asn1, "D", &extOID) == -1) { 9693089Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 9703089Swyllys goto cleanup; 9713089Swyllys } 9723089Swyllys 9733089Swyllys tag = kmfber_next_element(asn1, &size, end); 9743089Swyllys if (tag != BER_BOOLEAN) { 9753089Swyllys critical = 0; 9763089Swyllys if (tag != BER_OCTET_STRING) 9773089Swyllys goto cleanup; 9783089Swyllys } else { 9793089Swyllys if (kmfber_scanf(asn1, "b", &critical) == -1) 9803089Swyllys goto cleanup; 9813089Swyllys } 9823089Swyllys 9833089Swyllys tag = kmfber_next_element(asn1, &size, end); 9843089Swyllys if (tag != BER_OCTET_STRING) { 9853089Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 9863089Swyllys goto cleanup; 9873089Swyllys } 9883089Swyllys if (kmfber_scanf(asn1, "o", &extValue) == -1) { 9893089Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 9903089Swyllys goto cleanup; 9913089Swyllys } 9923089Swyllys 9933089Swyllys /* allocate a new Extension record */ 9943089Swyllys ex = malloc(sizeof (KMF_X509_EXTENSION)); 9953089Swyllys if (ex == NULL) { 9963089Swyllys ret = KMF_ERR_MEMORY; 9973089Swyllys goto cleanup; 9983089Swyllys } 9993089Swyllys (void) memset(ex, 0, sizeof (ex)); 10003089Swyllys 10013089Swyllys ex->extnId.Data = (uchar_t *)extOID.bv_val; 10023089Swyllys ex->extnId.Length = extOID.bv_len; 10033089Swyllys ex->critical = critical; 10043089Swyllys ex->format = KMF_X509_DATAFORMAT_ENCODED; 10053089Swyllys ex->BERvalue.Data = (uchar_t *)extValue.bv_val; 10063089Swyllys ex->BERvalue.Length = extValue.bv_len; 10073089Swyllys 10083089Swyllys /* Tag and value is a little tricky */ 10093089Swyllys ex->value.tagAndValue = malloc(sizeof (KMF_X509EXT_TAGandVALUE)); 10103089Swyllys if (ex->value.tagAndValue == NULL) { 10113089Swyllys ret = KMF_ERR_MEMORY; 10123089Swyllys goto cleanup; 10133089Swyllys } 10143089Swyllys (void) memset(ex->value.tagAndValue, 0, 10153089Swyllys sizeof (KMF_X509EXT_TAGandVALUE)); 10163089Swyllys 10173089Swyllys /* Parse the Extension value field */ 10183089Swyllys extnber = kmfder_init(&extValue); 10193089Swyllys if (extnber == NULL) { 10203089Swyllys ret = KMF_ERR_MEMORY; 10213089Swyllys goto cleanup; 10223089Swyllys } 10233089Swyllys 10243089Swyllys /* Get the tag and length of the extension field */ 10253089Swyllys if (kmfber_scanf(extnber, "tl", &tag, &size) == -1) { 10263089Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 10273089Swyllys goto cleanup; 10283089Swyllys } 10293089Swyllys 10303089Swyllys if (kmfber_scanf(extnber, "T", &tag) == -1) { 10313089Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 10323089Swyllys goto cleanup; 10333089Swyllys } 10343089Swyllys 10353089Swyllys ex->value.tagAndValue->value.Data = malloc(size); 10363089Swyllys ex->value.tagAndValue->value.Length = size; 10373089Swyllys size = kmfber_read(extnber, 10383089Swyllys (char *)ex->value.tagAndValue->value.Data, size); 10393089Swyllys if (size != ex->value.tagAndValue->value.Length) { 10403089Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 10413089Swyllys goto cleanup; 10423089Swyllys } 10433089Swyllys kmfber_free(extnber, 1); 10443089Swyllys ex->value.tagAndValue->type = tag; 10453089Swyllys 10463089Swyllys *retex = ex; 10473089Swyllys cleanup: 10483089Swyllys if (ret != KMF_OK) { 10493089Swyllys if (ex != NULL) 10503089Swyllys free_one_extension(ex); 10513089Swyllys } 10523089Swyllys 10533089Swyllys return (ret); 10543089Swyllys } 10553089Swyllys 10563089Swyllys static KMF_RETURN 10573089Swyllys get_extensions(BerElement *asn1, KMF_X509_EXTENSIONS *extns) 10583089Swyllys { 10593089Swyllys KMF_RETURN ret = KMF_OK; 10603089Swyllys ber_len_t size; 10613089Swyllys char *end = NULL; 10623089Swyllys KMF_X509_EXTENSION *ex = NULL; 10633089Swyllys 10643089Swyllys /* 10653089Swyllys * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension 10663089Swyllys * 10673089Swyllys * Extension ::= SEQUENCE { 10683089Swyllys * extnID OBJECT IDENTIFIER, 10693089Swyllys * critical BOOLEAN DEFAULT FALSE, 10703089Swyllys * extnValue OCTET STRING } 10713089Swyllys * 10723089Swyllys * { {{D}Bo}, ... } 10733089Swyllys */ 10743089Swyllys if (kmfber_first_element(asn1, &size, &end) != 10753089Swyllys BER_CONSTRUCTED_SEQUENCE) 10763089Swyllys return (KMF_ERR_BAD_CERT_FORMAT); 10773089Swyllys 10783089Swyllys while (kmfber_next_element(asn1, &size, end) == 10793089Swyllys BER_CONSTRUCTED_SEQUENCE) { 10803089Swyllys ret = get_one_extension(asn1, &ex, end); 10813089Swyllys if (ret != KMF_OK) 10823089Swyllys goto cleanup; 10833089Swyllys 10843089Swyllys extns->numberOfExtensions++; 10853089Swyllys extns->extensions = realloc(extns->extensions, 10863089Swyllys extns->numberOfExtensions * 10873089Swyllys sizeof (KMF_X509_EXTENSION)); 10883089Swyllys if (extns->extensions == NULL) { 10893089Swyllys ret = KMF_ERR_MEMORY; 10903089Swyllys break; 10913089Swyllys } 10923089Swyllys 10933089Swyllys extns->extensions[extns->numberOfExtensions-1] = *ex; 10943089Swyllys free(ex); 10953089Swyllys } 10963089Swyllys 10973089Swyllys cleanup: 10983089Swyllys if (ret != KMF_OK) 10993089Swyllys free_extensions(extns); 11003089Swyllys 11013089Swyllys return (ret); 11023089Swyllys } 11033089Swyllys 11043089Swyllys KMF_RETURN 11053089Swyllys decode_tbscert_data(BerElement *asn1, 11063089Swyllys KMF_X509_TBS_CERT **signed_cert_ptr_ptr) 11073089Swyllys { 11083089Swyllys KMF_RETURN ret = KMF_OK; 11093089Swyllys KMF_X509_TBS_CERT *tbscert = NULL; 11103089Swyllys int tag, version; 11113089Swyllys struct berval *bvserno = NULL; 11123089Swyllys KMF_BIGINT serno; 11133089Swyllys 11143089Swyllys if (kmfber_scanf(asn1, "{t", &tag) == -1) { 11153089Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 11163089Swyllys goto cleanup; 11173089Swyllys } 11183089Swyllys 11193089Swyllys /* Version number is optional */ 11203089Swyllys if (tag == 0xA0) { 11213089Swyllys if (kmfber_scanf(asn1, "Ti", &tag, &version) == -1) { 11223089Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 11233089Swyllys goto cleanup; 11243089Swyllys } 11253089Swyllys } else { 11263089Swyllys version = 0; /* DEFAULT v1 (0) */ 11273089Swyllys } 11283089Swyllys 11293089Swyllys /* Now get the serial number, it is not optional */ 11303089Swyllys if (kmfber_scanf(asn1, "I", &bvserno) == -1) { 11313089Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 11323089Swyllys goto cleanup; 11333089Swyllys } else { 11343089Swyllys serno.val = (uchar_t *)bvserno->bv_val; 11353089Swyllys serno.len = bvserno->bv_len; 11363089Swyllys } 11373089Swyllys 11383089Swyllys tbscert = malloc(sizeof (KMF_X509_TBS_CERT)); 11393089Swyllys if (!tbscert) { 11403089Swyllys ret = KMF_ERR_MEMORY; 11413089Swyllys goto cleanup; 11423089Swyllys } 11433089Swyllys 11443089Swyllys (void) memset(tbscert, 0, sizeof (KMF_X509_TBS_CERT)); 11453089Swyllys 11463089Swyllys if ((ret = set_der_integer(&tbscert->version, version)) != KMF_OK) 11473089Swyllys goto cleanup; 11483089Swyllys 11493089Swyllys if ((ret = set_bigint(&tbscert->serialNumber, &serno)) != KMF_OK) 11503089Swyllys goto cleanup; 11513089Swyllys 11523089Swyllys if ((ret = get_algoid(asn1, &tbscert->signature)) != KMF_OK) 11533089Swyllys goto cleanup; 11543089Swyllys 11553089Swyllys if ((ret = get_rdn(asn1, &tbscert->issuer)) != KMF_OK) 11563089Swyllys goto cleanup; 11573089Swyllys 11583089Swyllys if ((ret = get_validity(asn1, &tbscert->validity)) != KMF_OK) 11593089Swyllys goto cleanup; 11603089Swyllys 11613089Swyllys if ((ret = get_rdn(asn1, &tbscert->subject)) != KMF_OK) 11623089Swyllys goto cleanup; 11633089Swyllys 11643089Swyllys if ((ret = get_spki(asn1, &tbscert->subjectPublicKeyInfo)) != KMF_OK) 11653089Swyllys goto cleanup; 11663089Swyllys 11673089Swyllys /* Check for the optional fields */ 11683089Swyllys tbscert->extensions.numberOfExtensions = 0; 11693089Swyllys tbscert->extensions.extensions = NULL; 11703089Swyllys 11713089Swyllys while ((kmfber_scanf(asn1, "t", &tag)) != -1 && 11723089Swyllys (tag == 0xA1 || tag == 0xA2 || tag == 0xA3)) { 11733089Swyllys char *optfield; 11743089Swyllys ber_len_t len; 11753089Swyllys 11763089Swyllys /* consume the tag and length */ 11773089Swyllys (void) kmfber_scanf(asn1, "T", &tag); 11783089Swyllys switch (tag) { 11793089Swyllys case 0xA1: 11803089Swyllys if (kmfber_scanf(asn1, "B", &optfield, &len) != 11813089Swyllys BER_BIT_STRING) { 11823089Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 11833089Swyllys goto cleanup; 11843089Swyllys } 11853089Swyllys tbscert->issuerUniqueIdentifier.Data = 11863089Swyllys (uchar_t *)optfield; 11873089Swyllys tbscert->issuerUniqueIdentifier.Length = 11883089Swyllys len / 8; 11893089Swyllys break; 11903089Swyllys case 0xA2: 11913089Swyllys if (kmfber_scanf(asn1, "B", &optfield, &len) != 11923089Swyllys BER_BIT_STRING) { 11933089Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 11943089Swyllys goto cleanup; 11953089Swyllys } 11963089Swyllys tbscert->subjectUniqueIdentifier.Data = 11973089Swyllys (uchar_t *)optfield; 11983089Swyllys tbscert->subjectUniqueIdentifier.Length = 11993089Swyllys len / 8; 12003089Swyllys break; 12013089Swyllys case 0xA3: 12023089Swyllys ret = get_extensions(asn1, &tbscert->extensions); 12033089Swyllys break; 12043089Swyllys } 12053089Swyllys } 12063089Swyllys 12073089Swyllys *signed_cert_ptr_ptr = tbscert; 12083089Swyllys 12093089Swyllys cleanup: 12103089Swyllys if (bvserno != NULL) { 12113089Swyllys free(bvserno->bv_val); 12123089Swyllys free(bvserno); 12133089Swyllys } 12143089Swyllys if (ret != KMF_OK) { 12153089Swyllys if (tbscert) { 12163089Swyllys free_tbscert(tbscert); 12173089Swyllys free(tbscert); 12183089Swyllys } 12193089Swyllys *signed_cert_ptr_ptr = NULL; 12203089Swyllys } 12213089Swyllys return (ret); 12223089Swyllys } 12233089Swyllys 12243089Swyllys KMF_RETURN 12253089Swyllys DerDecodeTbsCertificate(const KMF_DATA *Value, 12263089Swyllys KMF_X509_TBS_CERT **tbscert) 12273089Swyllys { 12283089Swyllys KMF_RETURN ret = KMF_OK; 12293089Swyllys BerElement *asn1 = NULL; 12303089Swyllys BerValue rawcert; 12313089Swyllys KMF_X509_TBS_CERT *newcert = NULL; 12323089Swyllys 12333089Swyllys if (!tbscert || !Value || !Value->Data || !Value->Length) 12343089Swyllys return (KMF_ERR_BAD_PARAMETER); 12353089Swyllys 12363089Swyllys rawcert.bv_val = (char *)Value->Data; 12373089Swyllys rawcert.bv_len = Value->Length; 12383089Swyllys 12393089Swyllys if ((asn1 = kmfder_init(&rawcert)) == NULL) 12403089Swyllys return (KMF_ERR_MEMORY); 12413089Swyllys 12423089Swyllys ret = decode_tbscert_data(asn1, &newcert); 12433089Swyllys if (ret != KMF_OK) 12443089Swyllys goto cleanup; 12453089Swyllys 12463089Swyllys *tbscert = newcert; 12473089Swyllys 12483089Swyllys cleanup: 12493089Swyllys if (ret != KMF_OK) { 12503089Swyllys if (newcert) 12513089Swyllys free_tbscert(newcert); 12523089Swyllys *tbscert = NULL; 12533089Swyllys } 12543089Swyllys kmfber_free(asn1, 1); 12553089Swyllys 12563089Swyllys return (ret); 12573089Swyllys } 12583089Swyllys 12593089Swyllys /* 12603089Swyllys * Name: DerDecodeSignedCertificate 12613089Swyllys * 12623089Swyllys * Description: 12633089Swyllys * DER decodes the encoded X509 certificate 12643089Swyllys * 12653089Swyllys * Parameters: 12663089Swyllys * Value (input): DER encoded object that shd be decoded 12673089Swyllys * 12683089Swyllys * signed_cert_ptr_ptr (output) : Decoded KMF_X509_CERTIFICATE object 12693089Swyllys */ 12703089Swyllys KMF_RETURN 12713089Swyllys DerDecodeSignedCertificate(const KMF_DATA *Value, 12723089Swyllys KMF_X509_CERTIFICATE **signed_cert_ptr_ptr) 12733089Swyllys { 12743089Swyllys KMF_RETURN ret = KMF_OK; 12753089Swyllys BerElement *asn1 = NULL; 12763089Swyllys BerValue rawcert; 12773089Swyllys ber_tag_t tag; 12783089Swyllys ber_len_t size; 12793089Swyllys char *end = NULL; 12803089Swyllys char *signature; 12813089Swyllys KMF_X509_TBS_CERT *tbscert = NULL; 12823089Swyllys KMF_X509_CERTIFICATE *certptr = NULL; 12833089Swyllys 12843089Swyllys if (!signed_cert_ptr_ptr || !Value || !Value->Data || !Value->Length) 12853089Swyllys return (KMF_ERR_BAD_PARAMETER); 12863089Swyllys 12873089Swyllys rawcert.bv_val = (char *)Value->Data; 12883089Swyllys rawcert.bv_len = Value->Length; 12893089Swyllys 12903089Swyllys if ((asn1 = kmfder_init(&rawcert)) == NULL) 12913089Swyllys return (KMF_ERR_MEMORY); 12923089Swyllys 12933089Swyllys if (kmfber_first_element(asn1, &size, &end) != 12943089Swyllys BER_CONSTRUCTED_SEQUENCE) { 12953089Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 12963089Swyllys goto cleanup; 12973089Swyllys } 12983089Swyllys 12993089Swyllys certptr = malloc(sizeof (KMF_X509_CERTIFICATE)); 13003089Swyllys if (certptr == NULL) { 13013089Swyllys ret = KMF_ERR_MEMORY; 13023089Swyllys goto cleanup; 13033089Swyllys } 13043089Swyllys (void) memset(certptr, 0, sizeof (KMF_X509_CERTIFICATE)); 13053089Swyllys 13063089Swyllys ret = decode_tbscert_data(asn1, &tbscert); 13073089Swyllys if (ret != KMF_OK) 13083089Swyllys goto cleanup; 13093089Swyllys 13103089Swyllys certptr->certificate = *tbscert; 13113089Swyllys free(tbscert); 13123089Swyllys tbscert = NULL; 13133089Swyllys 13143089Swyllys /* 13153089Swyllys * The signature data my not be present yet. 13163089Swyllys */ 13173089Swyllys if ((ret = get_algoid(asn1, 13183089Swyllys &certptr->signature.algorithmIdentifier)) == KMF_OK) { 13193089Swyllys 13203089Swyllys /* Check to see if the cert has a signature yet */ 13213089Swyllys if (kmfber_next_element(asn1, &size, end) == BER_BIT_STRING) { 13223089Swyllys /* Finally, get the encrypted signature BITSTRING */ 13233089Swyllys if (kmfber_scanf(asn1, "tl", &tag, &size) == -1) { 13243089Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 13253089Swyllys goto cleanup; 13263089Swyllys } 13273089Swyllys if (tag != BER_BIT_STRING) { 13283089Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 13293089Swyllys goto cleanup; 13303089Swyllys } 13313089Swyllys if (kmfber_scanf(asn1, "B}", &signature, &size) == -1) { 13323089Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 13333089Swyllys goto cleanup; 13343089Swyllys } 13353089Swyllys certptr->signature.encrypted.Data = 13363089Swyllys (uchar_t *)signature; 13373089Swyllys certptr->signature.encrypted.Length = size / 8; 13383089Swyllys } else { 13393089Swyllys certptr->signature.encrypted.Data = NULL; 13403089Swyllys certptr->signature.encrypted.Length = 0; 13413089Swyllys } 13423089Swyllys } else { 13433089Swyllys (void) memset(&certptr->signature, 0, 13443089Swyllys sizeof (certptr->signature)); 13453089Swyllys ret = KMF_OK; 13463089Swyllys } 13473089Swyllys 13483089Swyllys *signed_cert_ptr_ptr = certptr; 13493089Swyllys cleanup: 13503089Swyllys if (ret != KMF_OK) { 13513089Swyllys if (certptr) { 13523089Swyllys free_decoded_cert(certptr); 13533089Swyllys free(certptr); 13543089Swyllys } 13553089Swyllys 13563089Swyllys *signed_cert_ptr_ptr = NULL; 13573089Swyllys } 13583089Swyllys if (asn1) 13593089Swyllys kmfber_free(asn1, 1); 13603089Swyllys 13613089Swyllys return (ret); 13623089Swyllys 13633089Swyllys } 13643089Swyllys 13653089Swyllys KMF_RETURN 13663089Swyllys DerDecodeExtension(KMF_DATA *Data, KMF_X509_EXTENSION **extn) 13673089Swyllys { 13683089Swyllys KMF_RETURN ret = KMF_OK; 13693089Swyllys BerElement *asn1 = NULL; 13703089Swyllys BerValue bv; 13713089Swyllys 13723089Swyllys bv.bv_val = (char *)Data->Data; 13733089Swyllys bv.bv_len = Data->Length; 13743089Swyllys 13753089Swyllys asn1 = kmfder_init(&bv); 13763089Swyllys if (asn1 == NULL) 13773089Swyllys return (KMF_ERR_MEMORY); 13783089Swyllys 13793089Swyllys ret = get_one_extension(asn1, extn, NULL); 13803089Swyllys 13813089Swyllys cleanup: 13823089Swyllys if (ret != KMF_OK) { 13833089Swyllys if (*extn != NULL) { 13843089Swyllys free(*extn); 13853089Swyllys } 13863089Swyllys *extn = NULL; 13873089Swyllys } 13883089Swyllys 13893089Swyllys kmfber_free(asn1, 1); 13903089Swyllys return (ret); 13913089Swyllys } 13923089Swyllys 13933089Swyllys KMF_RETURN 13943089Swyllys DerDecodeName(KMF_DATA *encodedname, KMF_X509_NAME *name) 13953089Swyllys { 13963089Swyllys KMF_RETURN ret = KMF_OK; 13973089Swyllys BerElement *asn1 = NULL; 13983089Swyllys BerValue bv; 13993089Swyllys 14003089Swyllys bv.bv_val = (char *)encodedname->Data; 14013089Swyllys bv.bv_len = encodedname->Length; 14023089Swyllys 14033089Swyllys asn1 = kmfder_init(&bv); 14043089Swyllys if (asn1 == NULL) 14053089Swyllys return (KMF_ERR_MEMORY); 14063089Swyllys 14073089Swyllys (void) memset((void *)name, 0, sizeof (KMF_X509_NAME)); 14083089Swyllys 14093089Swyllys if ((ret = get_rdn(asn1, name)) != KMF_OK) 14103089Swyllys goto cleanup; 14113089Swyllys 14123089Swyllys cleanup: 14133089Swyllys if (asn1) 14143089Swyllys kmfber_free(asn1, 1); 14153089Swyllys return (ret); 14163089Swyllys } 14173089Swyllys 14183089Swyllys KMF_RETURN 14193089Swyllys DerEncodeName(KMF_X509_NAME *name, KMF_DATA *encodedname) 14203089Swyllys { 14213089Swyllys KMF_RETURN ret = KMF_OK; 14223089Swyllys BerElement *asn1 = NULL; 14233089Swyllys BerValue *bv = NULL; 14243089Swyllys 14253089Swyllys asn1 = kmfder_alloc(); 14263089Swyllys if (asn1 == NULL) 14273089Swyllys return (KMF_ERR_MEMORY); 14283089Swyllys 14293089Swyllys if ((ret = encode_rdn(asn1, name)) != KMF_OK) 14303089Swyllys goto cleanup; 14313089Swyllys 14323089Swyllys if (kmfber_flatten(asn1, &bv) == -1) { 14333089Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 14343089Swyllys goto cleanup; 14353089Swyllys } 14363089Swyllys 14373089Swyllys encodedname->Data = (uchar_t *)bv->bv_val; 14383089Swyllys encodedname->Length = bv->bv_len; 14393089Swyllys 14403089Swyllys cleanup: 14413089Swyllys if (bv) 14423089Swyllys free(bv); 14433089Swyllys 14443089Swyllys if (asn1) 14453089Swyllys kmfber_free(asn1, 1); 14463089Swyllys 14473089Swyllys return (ret); 14483089Swyllys } 14493089Swyllys 14503089Swyllys static KMF_RETURN 14513089Swyllys encode_tbs_cert(BerElement *asn1, KMF_X509_TBS_CERT *tbscert) 14523089Swyllys { 14533089Swyllys KMF_RETURN ret = KMF_OK; 14543089Swyllys uint32_t version; 14553089Swyllys 14563089Swyllys /* version should be 4 bytes or less */ 14573089Swyllys if (tbscert->version.Length > sizeof (int)) 14583089Swyllys return (KMF_ERR_BAD_CERT_FORMAT); 14593089Swyllys 14603089Swyllys (void) memcpy(&version, tbscert->version.Data, 14613089Swyllys tbscert->version.Length); 14623089Swyllys 14633089Swyllys /* Start the sequence and add the version */ 14643089Swyllys if (kmfber_printf(asn1, "{Tli", 0xA0, 3, version) == -1) { 14653089Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 14663089Swyllys goto cleanup; 14673089Swyllys } 14683089Swyllys /* Write the serial number */ 14693089Swyllys if (kmfber_printf(asn1, "I", 14703089Swyllys (char *)tbscert->serialNumber.val, 14713089Swyllys (size_t)tbscert->serialNumber.len) == -1) { 14723089Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 14733089Swyllys goto cleanup; 14743089Swyllys } 14753089Swyllys 14763089Swyllys if ((ret = encode_algoid(asn1, &tbscert->signature)) != KMF_OK) 14773089Swyllys goto cleanup; 14783089Swyllys 14793089Swyllys /* Encode the Issuer RDN */ 14803089Swyllys if ((ret = encode_rdn(asn1, &tbscert->issuer)) != KMF_OK) 14813089Swyllys goto cleanup; 14823089Swyllys 14833089Swyllys /* Encode the Validity fields */ 14843089Swyllys if ((ret = encode_validity(asn1, &tbscert->validity)) != KMF_OK) 14853089Swyllys goto cleanup; 14863089Swyllys 14873089Swyllys /* Encode the Subject RDN */ 14883089Swyllys if ((ret = encode_rdn(asn1, &tbscert->subject)) != KMF_OK) 14893089Swyllys goto cleanup; 14903089Swyllys 14913089Swyllys /* Encode the Subject Public Key Info */ 14923089Swyllys if ((ret = encode_spki(asn1, &tbscert->subjectPublicKeyInfo)) != KMF_OK) 14933089Swyllys goto cleanup; 14943089Swyllys 14953089Swyllys /* Optional field: issuer Unique ID */ 14963089Swyllys if (tbscert->issuerUniqueIdentifier.Length > 0) { 14973089Swyllys if ((ret = encode_uniqueid(asn1, 0xA1, 14983089Swyllys &tbscert->issuerUniqueIdentifier)) != KMF_OK) 14993089Swyllys goto cleanup; 15003089Swyllys } 15013089Swyllys 15023089Swyllys /* Optional field: Subject Unique ID */ 15033089Swyllys if (tbscert->subjectUniqueIdentifier.Length > 0) { 15043089Swyllys if ((ret = encode_uniqueid(asn1, 0xA2, 15053089Swyllys &tbscert->subjectUniqueIdentifier)) != KMF_OK) 15063089Swyllys goto cleanup; 15073089Swyllys } 15083089Swyllys 15093089Swyllys /* Optional field: Certificate Extensions */ 15103089Swyllys if (tbscert->extensions.numberOfExtensions > 0) { 15113089Swyllys if ((ret = encode_extensions(asn1, 15123089Swyllys &tbscert->extensions)) != KMF_OK) 15133089Swyllys goto cleanup; 15143089Swyllys } 15153089Swyllys 15163089Swyllys /* Close out the TBSCert sequence */ 15173089Swyllys if (kmfber_printf(asn1, "}") == -1) { 15183089Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 15193089Swyllys goto cleanup; 15203089Swyllys } 15213089Swyllys 15223089Swyllys cleanup: 15233089Swyllys /* 15243089Swyllys * Memory cleanup is done in the caller or in the individual 15253089Swyllys * encoding routines. 15263089Swyllys */ 15273089Swyllys 15283089Swyllys return (ret); 15293089Swyllys } 15303089Swyllys 15313089Swyllys KMF_RETURN 15323089Swyllys DerEncodeTbsCertificate(KMF_X509_TBS_CERT *tbs_cert_ptr, 15333089Swyllys KMF_DATA *enc_tbs_cert_ptr) 15343089Swyllys { 15353089Swyllys KMF_RETURN ret; 15363089Swyllys BerElement *asn1 = NULL; 15373089Swyllys BerValue *tbsdata = NULL; 15383089Swyllys 15393089Swyllys asn1 = kmfder_alloc(); 15403089Swyllys if (asn1 == NULL) 15413089Swyllys return (KMF_ERR_MEMORY); 15423089Swyllys 15433089Swyllys enc_tbs_cert_ptr->Data = NULL; 15443089Swyllys enc_tbs_cert_ptr->Length = 0; 15453089Swyllys 15463089Swyllys ret = encode_tbs_cert(asn1, tbs_cert_ptr); 15473089Swyllys if (ret != KMF_OK) 15483089Swyllys goto cleanup; 15493089Swyllys 15503089Swyllys if (kmfber_flatten(asn1, &tbsdata) == -1) { 15513089Swyllys ret = KMF_ERR_MEMORY; 15523089Swyllys goto cleanup; 15533089Swyllys } 15543089Swyllys 15553089Swyllys enc_tbs_cert_ptr->Data = (uchar_t *)tbsdata->bv_val; 15563089Swyllys enc_tbs_cert_ptr->Length = tbsdata->bv_len; 15573089Swyllys 15583089Swyllys cleanup: 15593089Swyllys if (ret != KMF_OK) 15603089Swyllys free_data(enc_tbs_cert_ptr); 15613089Swyllys 15623089Swyllys if (asn1 != NULL) 15633089Swyllys kmfber_free(asn1, 1); 15643089Swyllys 15653089Swyllys if (tbsdata) 15663089Swyllys free(tbsdata); 15673089Swyllys 15683089Swyllys return (ret); 15693089Swyllys } 15703089Swyllys 15713089Swyllys KMF_RETURN 15723089Swyllys DerEncodeSignedCertificate(KMF_X509_CERTIFICATE *signed_cert_ptr, 15733089Swyllys KMF_DATA *encodedcert) 15743089Swyllys { 15753089Swyllys KMF_RETURN ret = KMF_OK; 15763089Swyllys KMF_X509_TBS_CERT *tbscert = NULL; 15773089Swyllys KMF_X509_SIGNATURE *signature = NULL; 15783089Swyllys BerElement *asn1 = NULL; 15793089Swyllys BerValue *tbsdata = NULL; 15803089Swyllys 15813089Swyllys if (signed_cert_ptr == NULL || encodedcert == NULL) 15823089Swyllys return (KMF_ERR_BAD_PARAMETER); 15833089Swyllys 15843089Swyllys encodedcert->Data = NULL; 15853089Swyllys encodedcert->Length = 0; 15863089Swyllys 15873089Swyllys tbscert = &signed_cert_ptr->certificate; 15883089Swyllys signature = &signed_cert_ptr->signature; 15893089Swyllys 15903089Swyllys asn1 = kmfder_alloc(); 15913089Swyllys if (asn1 == NULL) 15923089Swyllys return (KMF_ERR_MEMORY); 15933089Swyllys 15943089Swyllys /* Start outer X509 Certificate SEQUENCE */ 15953089Swyllys if (kmfber_printf(asn1, "{") == -1) { 15963089Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 15973089Swyllys goto cleanup; 15983089Swyllys } 15993089Swyllys 16003089Swyllys if ((ret = encode_tbs_cert(asn1, tbscert)) != KMF_OK) { 16013089Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 16023089Swyllys goto cleanup; 16033089Swyllys } 16043089Swyllys 16053089Swyllys /* Add the Algorithm & Signature Sequence */ 16063089Swyllys if ((ret = encode_algoid(asn1, 16073089Swyllys &signature->algorithmIdentifier)) != KMF_OK) 16083089Swyllys goto cleanup; 16093089Swyllys 16103089Swyllys if (signature->encrypted.Length > 0) { 16113089Swyllys if (kmfber_printf(asn1, "B", signature->encrypted.Data, 16123089Swyllys signature->encrypted.Length * 8) == -1) { 16133089Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 16143089Swyllys goto cleanup; 16153089Swyllys } 16163089Swyllys } 16173089Swyllys 16183089Swyllys if (kmfber_printf(asn1, "}") == -1) { 16193089Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 16203089Swyllys goto cleanup; 16213089Swyllys } 16223089Swyllys 16233089Swyllys if (kmfber_flatten(asn1, &tbsdata) == -1) { 16243089Swyllys ret = KMF_ERR_MEMORY; 16253089Swyllys goto cleanup; 16263089Swyllys } 16273089Swyllys 16283089Swyllys encodedcert->Data = (uchar_t *)tbsdata->bv_val; 16293089Swyllys encodedcert->Length = tbsdata->bv_len; 16303089Swyllys 16313089Swyllys cleanup: 16323089Swyllys if (ret != KMF_OK) 16333089Swyllys free_data(encodedcert); 16343089Swyllys 16353089Swyllys if (tbsdata) 16363089Swyllys free(tbsdata); 16373089Swyllys 16383089Swyllys if (asn1) 16393089Swyllys kmfber_free(asn1, 1); 16403089Swyllys 16413089Swyllys return (ret); 16423089Swyllys } 16433089Swyllys 16443089Swyllys KMF_RETURN 16453089Swyllys ExtractX509CertParts(KMF_DATA *x509cert, KMF_DATA *tbscert, 16463089Swyllys KMF_DATA *signature) 16473089Swyllys { 16483089Swyllys KMF_RETURN ret = KMF_OK; 16493089Swyllys BerElement *der = NULL; 16503089Swyllys BerValue x509; 16513089Swyllys ber_tag_t tag; 16523089Swyllys ber_len_t size; 16533089Swyllys 16543089Swyllys if (tbscert == NULL || x509cert == NULL) 16553089Swyllys return (KMF_ERR_BAD_PARAMETER); 16563089Swyllys 16573089Swyllys x509.bv_val = (char *)x509cert->Data; 16583089Swyllys x509.bv_len = x509cert->Length; 16593089Swyllys 16603089Swyllys der = kmfder_init(&x509); 16613089Swyllys if (der == NULL) 16623089Swyllys return (KMF_ERR_MEMORY); 16633089Swyllys 16643089Swyllys /* Skip over the overall Sequence tag to get at the TBS Cert data */ 16653089Swyllys if (kmfber_scanf(der, "Tl", &tag, &size) == -1) { 16663089Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 16673089Swyllys goto cleanup; 16683089Swyllys } 16693089Swyllys if (tag != BER_CONSTRUCTED_SEQUENCE) { 16703089Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 16713089Swyllys goto cleanup; 16723089Swyllys } 16733089Swyllys 16743089Swyllys /* 16753089Swyllys * Since we are extracting a copy of the ENCODED bytes, we 16763089Swyllys * must make sure to also include the bytes for the tag and 16773089Swyllys * the length fields for the CONSTRUCTED SEQUENCE (TBSCert). 16783089Swyllys */ 16793089Swyllys size += kmfber_calc_taglen(tag) + kmfber_calc_lenlen(size); 16803089Swyllys 16813089Swyllys tbscert->Data = malloc(size); 16823089Swyllys if (tbscert->Data == NULL) { 16833089Swyllys ret = KMF_ERR_MEMORY; 16843089Swyllys goto cleanup; 16853089Swyllys } 16863089Swyllys tbscert->Length = size; 16873089Swyllys 16883089Swyllys /* The der data ptr is now set to the start of the TBS cert sequence */ 16893089Swyllys size = kmfber_read(der, (char *)tbscert->Data, tbscert->Length); 16903089Swyllys if (size != tbscert->Length) { 16913089Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 16923089Swyllys goto cleanup; 16933089Swyllys } 16943089Swyllys 16953089Swyllys if (signature != NULL) { 16963089Swyllys KMF_X509_ALGORITHM_IDENTIFIER algoid; 16973089Swyllys if ((ret = get_algoid(der, &algoid)) != KMF_OK) 16983089Swyllys goto cleanup; 16993089Swyllys free_algoid(&algoid); 17003089Swyllys 17013089Swyllys if (kmfber_scanf(der, "tl", &tag, &size) != BER_BIT_STRING) { 17023089Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 17033089Swyllys goto cleanup; 17043089Swyllys } 17053089Swyllys /* Now get the signature data */ 17063089Swyllys if (kmfber_scanf(der, "B", (char **)&signature->Data, 17073089Swyllys (ber_len_t *)&signature->Length) == -1) { 17083089Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 17093089Swyllys goto cleanup; 17103089Swyllys } 17113089Swyllys /* convert bitstring length to bytes */ 17123089Swyllys signature->Length = signature->Length / 8; 17133089Swyllys } 17143089Swyllys 17153089Swyllys cleanup: 17163089Swyllys if (der) 17173089Swyllys kmfber_free(der, 1); 17183089Swyllys 17193089Swyllys if (ret != KMF_OK) 17203089Swyllys free_data(tbscert); 17213089Swyllys 17223089Swyllys return (ret); 17233089Swyllys } 17243089Swyllys 17253089Swyllys /* 17263089Swyllys * Name: GetKeyFromSpki 17273089Swyllys * 17283089Swyllys * Description: 17293089Swyllys * This function parses the KMF_X509_SPKI into its 17303089Swyllys * key and parameter components based on the key generation algorithm. 17313089Swyllys * NOTE: Currently, it only checks for the RSA and DSA algorithms. 17323089Swyllys * The RSA algorithm is equivalent to the default behavior. 17333089Swyllys * All other algorithms will default to the parameters = NULL and the 17343089Swyllys * key data equal to whatever is in the CSSM_KEY structure for the key 17353089Swyllys * 17363089Swyllys * Parameters: 17373089Swyllys * AlgId (input) : Algorithm identifier 17383089Swyllys * SpkiPtr (input): SPKI structure that contains the key 17393089Swyllys * key_ptr(output): The output key 17403089Swyllys * 17413089Swyllys */ 17423089Swyllys KMF_RETURN 17433089Swyllys GetKeyFromSpki(KMF_ALGORITHM_INDEX AlgId, 17443089Swyllys KMF_X509_SPKI *SpkiPtr, 17453089Swyllys KMF_DATA **key_ptr) 17463089Swyllys { 17473089Swyllys KMF_RETURN ret = KMF_OK; 17483089Swyllys BerElement *asn1; 17493089Swyllys BerValue *encodedkey = NULL; 17503089Swyllys 17513089Swyllys if (!key_ptr || !SpkiPtr) { 17523089Swyllys return (KMF_ERR_BAD_PARAMETER); 17533089Swyllys } 17543089Swyllys *key_ptr = NULL; 17553089Swyllys 17563089Swyllys switch (AlgId) { 17573089Swyllys case KMF_ALGID_DSA: 17583089Swyllys asn1 = kmfder_alloc(); 17593089Swyllys if (asn1 == NULL) { 17603089Swyllys return (KMF_ERR_MEMORY); 17613089Swyllys } 17623089Swyllys 17633089Swyllys if ((ret = encode_spki(asn1, SpkiPtr)) != KMF_OK) { 17643089Swyllys ret = KMF_ERR_MEMORY; 17653089Swyllys goto cleanup; 17663089Swyllys } 17673089Swyllys 17683089Swyllys if (kmfber_flatten(asn1, &encodedkey) == -1) { 17693089Swyllys ret = KMF_ERR_MEMORY; 17703089Swyllys goto cleanup; 17713089Swyllys } 17723089Swyllys 17733089Swyllys *key_ptr = malloc(sizeof (KMF_DATA)); 17743089Swyllys 17753089Swyllys if (!*key_ptr) { 17763089Swyllys ret = KMF_ERR_MEMORY; 17773089Swyllys goto cleanup; 17783089Swyllys } 17793089Swyllys 17803089Swyllys (*key_ptr)->Length = encodedkey->bv_len; 17813089Swyllys (*key_ptr)->Data = (uchar_t *)encodedkey->bv_val; 17823089Swyllys cleanup: 17833089Swyllys kmfber_free(asn1, 1); 17843089Swyllys if (encodedkey) 17853089Swyllys free(encodedkey); 17863089Swyllys break; 17873089Swyllys default: /* RSA */ 17883089Swyllys *key_ptr = malloc(sizeof (KMF_DATA)); 17893089Swyllys 17903089Swyllys if (!*key_ptr) { 17913089Swyllys return (KMF_ERR_MEMORY); 17923089Swyllys } 17933089Swyllys (*key_ptr)->Length = SpkiPtr->subjectPublicKey.Length; 17943089Swyllys (*key_ptr)->Data = malloc((*key_ptr)->Length); 17953089Swyllys 17963089Swyllys if (!(*key_ptr)->Data) { 17973089Swyllys free(*key_ptr); 17983089Swyllys *key_ptr = NULL; 17993089Swyllys return (KMF_ERR_MEMORY); 18003089Swyllys } 18013089Swyllys (void) memcpy((*key_ptr)->Data, 18023089Swyllys SpkiPtr->subjectPublicKey.Data, 18033089Swyllys (*key_ptr)->Length); 18043089Swyllys return (ret); 18053089Swyllys } 18063089Swyllys return (ret); 18073089Swyllys } 18083089Swyllys 18093089Swyllys static KMF_RETURN 18103089Swyllys decode_csr_extensions(BerElement *asn1, KMF_X509_EXTENSIONS *extns) 18113089Swyllys { 18123089Swyllys KMF_RETURN ret = KMF_OK; 18133089Swyllys BerValue oid; 18143089Swyllys 18153089Swyllys if (kmfber_scanf(asn1, "{D", &oid) == -1) { 18163089Swyllys return (KMF_ERR_UNKNOWN_CSR_ATTRIBUTE); 18173089Swyllys } 18183089Swyllys 18193089Swyllys /* We only understand extension requests in a CSR */ 18203089Swyllys if (memcmp(oid.bv_val, extension_request_oid.Data, 18213089Swyllys oid.bv_len) != 0) { 18223089Swyllys return (KMF_ERR_UNKNOWN_CSR_ATTRIBUTE); 18233089Swyllys } 18243089Swyllys 18253089Swyllys if (kmfber_scanf(asn1, "[") == -1) { 18263089Swyllys return (KMF_ERR_ENCODING); 18273089Swyllys } 18283089Swyllys ret = get_extensions(asn1, extns); 18293089Swyllys 18303089Swyllys 18313089Swyllys return (ret); 18323089Swyllys } 18333089Swyllys 18343089Swyllys static KMF_RETURN 18353089Swyllys decode_tbscsr_data(BerElement *asn1, 18363089Swyllys KMF_TBS_CSR **signed_csr_ptr_ptr) 18373089Swyllys { 18383089Swyllys KMF_RETURN ret = KMF_OK; 18393089Swyllys KMF_TBS_CSR *tbscsr = NULL; 18403089Swyllys char *end = NULL; 18413089Swyllys uint32_t version; 18423089Swyllys ber_tag_t tag; 18433089Swyllys ber_len_t size; 18443089Swyllys 18453089Swyllys /* Now get the version number, it is not optional */ 18463089Swyllys if (kmfber_scanf(asn1, "{i", &version) == -1) { 18473089Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 18483089Swyllys goto cleanup; 18493089Swyllys } 18503089Swyllys 18513089Swyllys tbscsr = malloc(sizeof (KMF_TBS_CSR)); 18523089Swyllys if (!tbscsr) { 18533089Swyllys ret = KMF_ERR_MEMORY; 18543089Swyllys goto cleanup; 18553089Swyllys } 18563089Swyllys 18573089Swyllys (void) memset(tbscsr, 0, sizeof (KMF_TBS_CSR)); 18583089Swyllys 18593089Swyllys if ((ret = set_der_integer(&tbscsr->version, version)) != KMF_OK) 18603089Swyllys goto cleanup; 18613089Swyllys 18623089Swyllys if ((ret = get_rdn(asn1, &tbscsr->subject)) != KMF_OK) 18633089Swyllys goto cleanup; 18643089Swyllys 18653089Swyllys if ((ret = get_spki(asn1, &tbscsr->subjectPublicKeyInfo)) != KMF_OK) 18663089Swyllys goto cleanup; 18673089Swyllys 18683089Swyllys /* Check for the optional fields (attributes) */ 18693089Swyllys if (kmfber_next_element(asn1, &size, end) == 0xA0) { 18703089Swyllys if (kmfber_scanf(asn1, "Tl", &tag, &size) == -1) { 18713089Swyllys ret = KMF_ERR_ENCODING; 18723089Swyllys goto cleanup; 18733089Swyllys } 18743089Swyllys 18753089Swyllys ret = decode_csr_extensions(asn1, &tbscsr->extensions); 18763089Swyllys } 18773089Swyllys if (ret == KMF_OK) 18783089Swyllys *signed_csr_ptr_ptr = tbscsr; 18793089Swyllys 18803089Swyllys cleanup: 18813089Swyllys if (ret != KMF_OK) { 18823089Swyllys if (tbscsr) { 18833089Swyllys free_tbscsr(tbscsr); 18843089Swyllys free(tbscsr); 18853089Swyllys } 18863089Swyllys *signed_csr_ptr_ptr = NULL; 18873089Swyllys } 18883089Swyllys return (ret); 18893089Swyllys } 18903089Swyllys 18913089Swyllys KMF_RETURN 18923089Swyllys DerDecodeTbsCsr(const KMF_DATA *Value, 18933089Swyllys KMF_TBS_CSR **tbscsr) 18943089Swyllys { 18953089Swyllys KMF_RETURN ret = KMF_OK; 18963089Swyllys BerElement *asn1 = NULL; 18973089Swyllys BerValue rawcsr; 18983089Swyllys KMF_TBS_CSR *newcsr = NULL; 18993089Swyllys 19003089Swyllys if (!tbscsr || !Value || !Value->Data || !Value->Length) 19013089Swyllys return (KMF_ERR_BAD_PARAMETER); 19023089Swyllys 19033089Swyllys rawcsr.bv_val = (char *)Value->Data; 19043089Swyllys rawcsr.bv_len = Value->Length; 19053089Swyllys 19063089Swyllys if ((asn1 = kmfder_init(&rawcsr)) == NULL) 19073089Swyllys return (KMF_ERR_MEMORY); 19083089Swyllys 19093089Swyllys ret = decode_tbscsr_data(asn1, &newcsr); 19103089Swyllys if (ret != KMF_OK) 19113089Swyllys goto cleanup; 19123089Swyllys 19133089Swyllys *tbscsr = newcsr; 19143089Swyllys 19153089Swyllys cleanup: 19163089Swyllys if (ret != KMF_OK) { 19173089Swyllys if (newcsr) 19183089Swyllys free_tbscsr(newcsr); 19193089Swyllys *tbscsr = NULL; 19203089Swyllys } 19213089Swyllys kmfber_free(asn1, 1); 19223089Swyllys 19233089Swyllys return (ret); 19243089Swyllys } 19253089Swyllys 19263089Swyllys KMF_RETURN 19273089Swyllys DerDecodeSignedCsr(const KMF_DATA *Value, 19283089Swyllys KMF_CSR_DATA **signed_csr_ptr_ptr) 19293089Swyllys { 19303089Swyllys KMF_RETURN ret = KMF_OK; 19313089Swyllys BerElement *asn1 = NULL; 19323089Swyllys BerValue rawcsr; 19333089Swyllys int tag; 19343089Swyllys ber_len_t size; 19353089Swyllys char *end = NULL; 19363089Swyllys char *signature; 19373089Swyllys KMF_TBS_CSR *tbscsr = NULL; 19383089Swyllys KMF_CSR_DATA *csrptr = NULL; 19393089Swyllys 19403089Swyllys if (!signed_csr_ptr_ptr || !Value || !Value->Data || !Value->Length) 19413089Swyllys return (KMF_ERR_BAD_PARAMETER); 19423089Swyllys 19433089Swyllys rawcsr.bv_val = (char *)Value->Data; 19443089Swyllys rawcsr.bv_len = Value->Length; 19453089Swyllys 19463089Swyllys if ((asn1 = kmfder_init(&rawcsr)) == NULL) 19473089Swyllys return (KMF_ERR_MEMORY); 19483089Swyllys 19493089Swyllys if (kmfber_first_element(asn1, &size, &end) != 19503089Swyllys BER_CONSTRUCTED_SEQUENCE) { 19513089Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 19523089Swyllys goto cleanup; 19533089Swyllys } 19543089Swyllys 19553089Swyllys csrptr = malloc(sizeof (KMF_CSR_DATA)); 19563089Swyllys if (csrptr == NULL) { 19573089Swyllys ret = KMF_ERR_MEMORY; 19583089Swyllys goto cleanup; 19593089Swyllys } 19603089Swyllys (void) memset(csrptr, 0, sizeof (KMF_CSR_DATA)); 19613089Swyllys 19623089Swyllys ret = decode_tbscsr_data(asn1, &tbscsr); 19633089Swyllys if (ret != KMF_OK) 19643089Swyllys goto cleanup; 19653089Swyllys 19663089Swyllys csrptr->csr = *tbscsr; 19673089Swyllys free(tbscsr); 19683089Swyllys tbscsr = NULL; 19693089Swyllys 19703089Swyllys if ((ret = get_algoid(asn1, 19713089Swyllys &csrptr->signature.algorithmIdentifier)) != KMF_OK) 19723089Swyllys goto cleanup; 19733089Swyllys 19743089Swyllys /* Check to see if the cert has a signature yet */ 19753089Swyllys if (kmfber_next_element(asn1, &size, end) == BER_BIT_STRING) { 19763089Swyllys /* Finally, get the encrypted signature BITSTRING */ 19773089Swyllys if (kmfber_scanf(asn1, "tl", &tag, &size) == -1) { 19783089Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 19793089Swyllys goto cleanup; 19803089Swyllys } 19813089Swyllys if (tag != BER_BIT_STRING) { 19823089Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 19833089Swyllys goto cleanup; 19843089Swyllys } 19853089Swyllys if (kmfber_scanf(asn1, "B}", &signature, &size) == -1) { 19863089Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 19873089Swyllys goto cleanup; 19883089Swyllys } 19893089Swyllys csrptr->signature.encrypted.Data = (uchar_t *)signature; 19903089Swyllys csrptr->signature.encrypted.Length = size / 8; 19913089Swyllys } else { 19923089Swyllys csrptr->signature.encrypted.Data = NULL; 19933089Swyllys csrptr->signature.encrypted.Length = 0; 19943089Swyllys } 19953089Swyllys 19963089Swyllys *signed_csr_ptr_ptr = csrptr; 19973089Swyllys cleanup: 19983089Swyllys if (ret != KMF_OK) { 19993089Swyllys free_tbscsr(&csrptr->csr); 20003089Swyllys free_algoid(&csrptr->signature.algorithmIdentifier); 20013089Swyllys if (csrptr->signature.encrypted.Data) 20023089Swyllys free(csrptr->signature.encrypted.Data); 20033089Swyllys 20043089Swyllys if (csrptr) 20053089Swyllys free(csrptr); 20063089Swyllys 20073089Swyllys *signed_csr_ptr_ptr = NULL; 20083089Swyllys } 20093089Swyllys if (asn1) 20103089Swyllys kmfber_free(asn1, 1); 20113089Swyllys 20123089Swyllys return (ret); 20133089Swyllys 20143089Swyllys } 20153089Swyllys 20163089Swyllys static KMF_RETURN 20173089Swyllys encode_csr_extensions(BerElement *asn1, KMF_TBS_CSR *tbscsr) 20183089Swyllys { 20193089Swyllys KMF_RETURN ret = KMF_OK; 20203089Swyllys int attlen = 0; 20213089Swyllys BerElement *extnasn1 = NULL; 20223089Swyllys BerValue *extnvalue = NULL; 20233089Swyllys 20243089Swyllys /* Optional field: CSR attributes and extensions */ 20253089Swyllys if (tbscsr->extensions.numberOfExtensions > 0) { 20263089Swyllys if (kmfber_printf(asn1, "T", 0xA0) == -1) { 20273089Swyllys ret = KMF_ERR_ENCODING; 20283089Swyllys goto cleanup; 20293089Swyllys } 20303089Swyllys } else { 20313089Swyllys /* No extensions or attributes to encode */ 20323089Swyllys return (KMF_OK); 20333089Swyllys } 20343089Swyllys 20353089Swyllys /* 20363089Swyllys * attributes [0] Attributes 20373089Swyllys * Attributes := SET OF Attribute 20383089Swyllys * Attribute := SEQUENCE { 20393089Swyllys * { ATTRIBUTE ID 20403089Swyllys * values SET SIZE(1..MAX) of ATTRIBUTE 20413089Swyllys * } 20423089Swyllys * 20433089Swyllys * Ex: { ExtensionRequest OID [ { {extn1 } , {extn2 } } ] } 20443089Swyllys */ 20453089Swyllys 20463089Swyllys /* 20473089Swyllys * Encode any extensions and add to the attributes section. 20483089Swyllys */ 20493089Swyllys if (tbscsr->extensions.numberOfExtensions > 0) { 20503089Swyllys extnasn1 = kmfder_alloc(); 20513089Swyllys if (extnasn1 == NULL) { 20523089Swyllys ret = KMF_ERR_MEMORY; 20533089Swyllys goto cleanup; 20543089Swyllys } 20553089Swyllys 20563089Swyllys if (kmfber_printf(extnasn1, "{D[{", 20573089Swyllys &extension_request_oid) == -1) { 20583089Swyllys ret = KMF_ERR_ENCODING; 20593089Swyllys goto cleanup_1; 20603089Swyllys } 20613089Swyllys 20623089Swyllys if ((ret = encode_extension_list(extnasn1, 20633089Swyllys &tbscsr->extensions)) != KMF_OK) { 20643089Swyllys goto cleanup_1; 20653089Swyllys } 20663089Swyllys 20673089Swyllys if (kmfber_printf(extnasn1, "}]}") == -1) { 20683089Swyllys ret = KMF_ERR_ENCODING; 20693089Swyllys goto cleanup_1; 20703089Swyllys } 20713089Swyllys 20723089Swyllys if (kmfber_flatten(extnasn1, &extnvalue) == -1) { 20733089Swyllys ret = KMF_ERR_MEMORY; 20743089Swyllys goto cleanup_1; 20753089Swyllys } 20763089Swyllys cleanup_1: 20773089Swyllys kmfber_free(extnasn1, 1); 20783089Swyllys 20793089Swyllys if (ret == KMF_OK) 20803089Swyllys /* Add 2 bytes to cover the tag and the length */ 20813089Swyllys attlen = extnvalue->bv_len; 20823089Swyllys } 20833089Swyllys if (ret != KMF_OK) 20843089Swyllys goto cleanup; 20853089Swyllys 20863089Swyllys if (kmfber_printf(asn1, "l", attlen) == -1) { 20873089Swyllys ret = KMF_ERR_ENCODING; 20883089Swyllys goto cleanup; 20893089Swyllys } 20903089Swyllys 20913089Swyllys /* Write the actual encoded extensions */ 20923089Swyllys if (extnvalue != NULL && extnvalue->bv_val != NULL) { 20933089Swyllys if (kmfber_write(asn1, extnvalue->bv_val, 20943089Swyllys extnvalue->bv_len, 0) == -1) { 20953089Swyllys ret = KMF_ERR_ENCODING; 20963089Swyllys goto cleanup; 20973089Swyllys } 20983089Swyllys } 20993089Swyllys 21003089Swyllys cleanup: 21013089Swyllys /* 21023089Swyllys * Memory cleanup is done in the caller or in the individual 21033089Swyllys * encoding routines. 21043089Swyllys */ 21053089Swyllys if (extnvalue) { 21063089Swyllys if (extnvalue->bv_val) 21073089Swyllys free(extnvalue->bv_val); 21083089Swyllys free(extnvalue); 21093089Swyllys } 21103089Swyllys 21113089Swyllys return (ret); 21123089Swyllys } 21133089Swyllys 21143089Swyllys static KMF_RETURN 21153089Swyllys encode_tbs_csr(BerElement *asn1, KMF_TBS_CSR *tbscsr) 21163089Swyllys { 21173089Swyllys KMF_RETURN ret = KMF_OK; 21183089Swyllys uint32_t version; 21193089Swyllys 21203089Swyllys /* Start the version */ 21213089Swyllys (void) memcpy(&version, tbscsr->version.Data, 21223089Swyllys tbscsr->version.Length); 21233089Swyllys 21243890Swyllys if (kmfber_printf(asn1, "{i", version) == -1) { 21253089Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 21263089Swyllys goto cleanup; 21273089Swyllys } 21283089Swyllys 21293089Swyllys /* Encode the Subject RDN */ 21303089Swyllys if ((ret = encode_rdn(asn1, &tbscsr->subject)) != KMF_OK) 21313089Swyllys goto cleanup; 21323089Swyllys 21333089Swyllys /* Encode the Subject Public Key Info */ 21343089Swyllys if ((ret = encode_spki(asn1, &tbscsr->subjectPublicKeyInfo)) != KMF_OK) 21353089Swyllys goto cleanup; 21363089Swyllys 21373089Swyllys 21383089Swyllys if ((ret = encode_csr_extensions(asn1, tbscsr)) != KMF_OK) 21393089Swyllys goto cleanup; 21403089Swyllys 21413089Swyllys /* Close out the TBSCert sequence */ 21423089Swyllys if (kmfber_printf(asn1, "}") == -1) { 21433089Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 21443089Swyllys goto cleanup; 21453089Swyllys } 21463089Swyllys 21473089Swyllys cleanup: 21483089Swyllys return (ret); 21493089Swyllys } 21503089Swyllys 21513089Swyllys KMF_RETURN 21523089Swyllys DerEncodeDSAPrivateKey(KMF_DATA *encodedkey, KMF_RAW_DSA_KEY *dsa) 21533089Swyllys { 21543089Swyllys KMF_RETURN rv = KMF_OK; 21553089Swyllys BerElement *asn1 = NULL; 21563089Swyllys BerValue *dsadata = NULL; 21573089Swyllys 21583089Swyllys asn1 = kmfder_alloc(); 21593089Swyllys if (asn1 == NULL) 21603089Swyllys return (KMF_ERR_MEMORY); 21613089Swyllys 21623089Swyllys if (kmfber_printf(asn1, "I", 21633089Swyllys dsa->value.val, dsa->value.len) == -1) { 21643089Swyllys rv = KMF_ERR_MEMORY; 21653089Swyllys goto cleanup; 21663089Swyllys } 21673089Swyllys 21683089Swyllys if (kmfber_flatten(asn1, &dsadata) == -1) { 21693089Swyllys rv = KMF_ERR_MEMORY; 21703089Swyllys goto cleanup; 21713089Swyllys } 21723089Swyllys 21733089Swyllys encodedkey->Data = (uchar_t *)dsadata->bv_val; 21743089Swyllys encodedkey->Length = dsadata->bv_len; 21753089Swyllys 21763089Swyllys free(dsadata); 21773089Swyllys cleanup: 21783089Swyllys kmfber_free(asn1, 1); 21793089Swyllys return (rv); 21803089Swyllys } 21813089Swyllys 21823089Swyllys KMF_RETURN 21833089Swyllys DerEncodeRSAPrivateKey(KMF_DATA *encodedkey, KMF_RAW_RSA_KEY *rsa) 21843089Swyllys { 21853089Swyllys KMF_RETURN rv = KMF_OK; 21863089Swyllys BerElement *asn1 = NULL; 21873089Swyllys uchar_t ver = 0; 21883089Swyllys BerValue *rsadata = NULL; 21893089Swyllys 21903089Swyllys asn1 = kmfder_alloc(); 21913089Swyllys if (asn1 == NULL) 21923089Swyllys return (KMF_ERR_MEMORY); 21933089Swyllys 21943089Swyllys if (kmfber_printf(asn1, "{IIIIIIIII}", 21953089Swyllys &ver, 1, 21963089Swyllys rsa->mod.val, rsa->mod.len, 21973089Swyllys rsa->pubexp.val, rsa->pubexp.len, 21983089Swyllys rsa->priexp.val, rsa->priexp.len, 21993089Swyllys rsa->prime1.val, rsa->prime1.len, 22003089Swyllys rsa->prime2.val, rsa->prime2.len, 22013089Swyllys rsa->exp1.val, rsa->exp1.len, 22023089Swyllys rsa->exp2.val, rsa->exp2.len, 22033089Swyllys rsa->coef.val, rsa->coef.len) == -1) 22043089Swyllys goto cleanup; 22053089Swyllys 22063089Swyllys if (kmfber_flatten(asn1, &rsadata) == -1) { 22073089Swyllys rv = KMF_ERR_MEMORY; 22083089Swyllys goto cleanup; 22093089Swyllys } 22103089Swyllys 22113089Swyllys encodedkey->Data = (uchar_t *)rsadata->bv_val; 22123089Swyllys encodedkey->Length = rsadata->bv_len; 22133089Swyllys 22143089Swyllys free(rsadata); 22153089Swyllys cleanup: 22163089Swyllys kmfber_free(asn1, 1); 22173089Swyllys return (rv); 22183089Swyllys } 22193089Swyllys 22203089Swyllys 22213089Swyllys KMF_RETURN 22223089Swyllys DerEncodeTbsCsr(KMF_TBS_CSR *tbs_csr_ptr, 22233089Swyllys KMF_DATA *enc_tbs_csr_ptr) 22243089Swyllys { 22253089Swyllys KMF_RETURN ret; 22263089Swyllys BerValue *tbsdata = NULL; 22273089Swyllys BerElement *asn1 = NULL; 22283089Swyllys 22293089Swyllys asn1 = kmfder_alloc(); 22303089Swyllys 22313089Swyllys enc_tbs_csr_ptr->Data = NULL; 22323089Swyllys enc_tbs_csr_ptr->Length = 0; 22333089Swyllys 22343089Swyllys if (asn1 == NULL) 22353089Swyllys return (KMF_ERR_MEMORY); 22363089Swyllys 22373089Swyllys ret = encode_tbs_csr(asn1, tbs_csr_ptr); 22383089Swyllys if (ret != KMF_OK) 22393089Swyllys goto cleanup; 22403089Swyllys 22413089Swyllys if (kmfber_flatten(asn1, &tbsdata) == -1) { 22423089Swyllys ret = KMF_ERR_MEMORY; 22433089Swyllys goto cleanup; 22443089Swyllys } 22453089Swyllys 22463089Swyllys enc_tbs_csr_ptr->Data = (uchar_t *)tbsdata->bv_val; 22473089Swyllys enc_tbs_csr_ptr->Length = tbsdata->bv_len; 22483089Swyllys 22493089Swyllys cleanup: 22503089Swyllys if (ret != KMF_OK) 22513089Swyllys free_data(enc_tbs_csr_ptr); 22523089Swyllys 22533089Swyllys if (asn1 != NULL) 22543089Swyllys kmfber_free(asn1, 1); 22553089Swyllys 22563089Swyllys if (tbsdata) 22573089Swyllys free(tbsdata); 22583089Swyllys 22593089Swyllys return (ret); 22603089Swyllys } 22613089Swyllys 22623089Swyllys KMF_RETURN 22633089Swyllys DerEncodeSignedCsr(KMF_CSR_DATA *signed_csr_ptr, 22643089Swyllys KMF_DATA *encodedcsr) 22653089Swyllys { 22663089Swyllys KMF_RETURN ret = KMF_OK; 22673089Swyllys KMF_TBS_CSR *tbscsr = NULL; 22683089Swyllys KMF_X509_SIGNATURE *signature = NULL; 22693089Swyllys BerElement *asn1 = NULL; 22703089Swyllys BerValue *tbsdata = NULL; 22713089Swyllys 22723089Swyllys if (signed_csr_ptr == NULL) 22733089Swyllys return (KMF_ERR_BAD_PARAMETER); 22743089Swyllys 22753089Swyllys tbscsr = &signed_csr_ptr->csr; 22763089Swyllys signature = &signed_csr_ptr->signature; 22773089Swyllys 22783089Swyllys asn1 = kmfder_alloc(); 22793089Swyllys if (asn1 == NULL) 22803089Swyllys return (KMF_ERR_MEMORY); 22813089Swyllys 22823089Swyllys /* Start outer CSR SEQUENCE */ 22833089Swyllys if (kmfber_printf(asn1, "{") == -1) { 22843089Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 22853089Swyllys goto cleanup; 22863089Swyllys } 22873089Swyllys 22883089Swyllys ret = encode_tbs_csr(asn1, tbscsr); 22893089Swyllys 22903089Swyllys /* Add the Algorithm & Signature Sequence */ 22913089Swyllys if ((ret = encode_algoid(asn1, 22923089Swyllys &signature->algorithmIdentifier)) != KMF_OK) 22933089Swyllys goto cleanup; 22943089Swyllys 22953089Swyllys if (signature->encrypted.Length > 0) { 22963089Swyllys if (kmfber_printf(asn1, "B", signature->encrypted.Data, 22973089Swyllys signature->encrypted.Length * 8) == -1) { 22983089Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 22993089Swyllys goto cleanup; 23003089Swyllys } 23013089Swyllys } 23023089Swyllys 23033089Swyllys if (kmfber_printf(asn1, "}") == -1) { 23043089Swyllys ret = KMF_ERR_BAD_CERT_FORMAT; 23053089Swyllys goto cleanup; 23063089Swyllys } 23073089Swyllys 23083089Swyllys if (kmfber_flatten(asn1, &tbsdata) == -1) { 23093089Swyllys ret = KMF_ERR_MEMORY; 23103089Swyllys goto cleanup; 23113089Swyllys } 23123089Swyllys 23133089Swyllys encodedcsr->Data = (uchar_t *)tbsdata->bv_val; 23143089Swyllys encodedcsr->Length = tbsdata->bv_len; 23153089Swyllys 23163089Swyllys cleanup: 23173089Swyllys if (ret != KMF_OK) { 23183089Swyllys free_data(encodedcsr); 23193089Swyllys } 23203089Swyllys 23213089Swyllys if (tbsdata) 23223089Swyllys free(tbsdata); 23233089Swyllys 23243089Swyllys if (asn1) 23253089Swyllys kmfber_free(asn1, 1); 23263089Swyllys return (ret); 23273089Swyllys } 23283089Swyllys 23293089Swyllys KMF_RETURN 23303089Swyllys ExtractSPKIData( 23313089Swyllys const KMF_X509_SPKI *pKey, 23323089Swyllys KMF_ALGORITHM_INDEX AlgorithmId, 23333089Swyllys KMF_DATA *pKeyParts, 23343089Swyllys uint32_t *uNumKeyParts) 23353089Swyllys { 23363089Swyllys KMF_RETURN ret = KMF_OK; 23373089Swyllys BerElement *asn1 = NULL; 23383089Swyllys BerValue *P, *Q, *G, *Mod, *Exp, *PubKey; 23393089Swyllys BerValue PubKeyParams, PubKeyData; 23403089Swyllys 23413089Swyllys if (pKeyParts == NULL || uNumKeyParts == NULL || pKey == NULL) 23423089Swyllys return (KMF_ERR_BAD_PARAMETER); 23433089Swyllys 23443089Swyllys switch (AlgorithmId) { 23453089Swyllys case KMF_ALGID_DSA: 23463089Swyllys case KMF_ALGID_SHA1WithDSA: 23473089Swyllys /* First, get the parameters from the algorithm definition */ 23483089Swyllys PubKeyParams.bv_val = (char *)pKey->algorithm.parameters.Data; 23493089Swyllys PubKeyParams.bv_len = pKey->algorithm.parameters.Length; 23503089Swyllys if ((asn1 = kmfder_init(&PubKeyParams)) == NULL) 23513089Swyllys return (KMF_ERR_MEMORY); 23523089Swyllys 23533089Swyllys if (kmfber_scanf(asn1, "{III}", &P, &Q, &G) == -1) { 23543089Swyllys kmfber_free(asn1, 1); 23553089Swyllys return (KMF_ERR_BAD_KEY_FORMAT); 23563089Swyllys } 23573089Swyllys pKeyParts[KMF_DSA_PRIME].Data = (uchar_t *)P->bv_val; 23583089Swyllys pKeyParts[KMF_DSA_PRIME].Length = P->bv_len; 23593089Swyllys pKeyParts[KMF_DSA_SUB_PRIME].Data = (uchar_t *)Q->bv_val; 23603089Swyllys pKeyParts[KMF_DSA_SUB_PRIME].Length = Q->bv_len; 23613089Swyllys pKeyParts[KMF_DSA_BASE].Data = (uchar_t *)G->bv_val; 23623089Swyllys pKeyParts[KMF_DSA_BASE].Length = G->bv_len; 23633089Swyllys 23643089Swyllys free(P); 23653089Swyllys free(Q); 23663089Swyllys free(G); 23673089Swyllys kmfber_free(asn1, 1); 23683089Swyllys 23693089Swyllys /* Get the PubKey data */ 23703089Swyllys PubKeyData.bv_val = (char *)pKey->subjectPublicKey.Data; 23713089Swyllys PubKeyData.bv_len = pKey->subjectPublicKey.Length; 23723089Swyllys if ((asn1 = kmfder_init(&PubKeyData)) == NULL) { 23733089Swyllys ret = KMF_ERR_MEMORY; 23743089Swyllys goto cleanup; 23753089Swyllys } 23763089Swyllys PubKey = NULL; 23773089Swyllys if (kmfber_scanf(asn1, "I", &PubKey) == -1) { 23783089Swyllys ret = KMF_ERR_BAD_KEY_FORMAT; 23793089Swyllys goto cleanup; 23803089Swyllys } 23813089Swyllys pKeyParts[KMF_DSA_PUBLIC_VALUE].Data = 23823089Swyllys (uchar_t *)PubKey->bv_val; 23833089Swyllys pKeyParts[KMF_DSA_PUBLIC_VALUE].Length = PubKey->bv_len; 23843089Swyllys 23853089Swyllys free(PubKey); 23863089Swyllys 23873089Swyllys *uNumKeyParts = KMF_NUMBER_DSA_PUBLIC_KEY_PARTS; 23883089Swyllys break; 23893089Swyllys 23903089Swyllys case KMF_ALGID_RSA: 23913089Swyllys case KMF_ALGID_MD2WithRSA: 23923089Swyllys case KMF_ALGID_MD5WithRSA: 23933089Swyllys case KMF_ALGID_SHA1WithRSA: 23943089Swyllys PubKeyData.bv_val = (char *)pKey->subjectPublicKey.Data; 23953089Swyllys PubKeyData.bv_len = pKey->subjectPublicKey.Length; 23963089Swyllys if ((asn1 = kmfder_init(&PubKeyData)) == NULL) { 23973089Swyllys ret = KMF_ERR_MEMORY; 23983089Swyllys goto cleanup; 23993089Swyllys } 24003089Swyllys if (kmfber_scanf(asn1, "{II}", &Mod, &Exp) == -1) { 24013089Swyllys ret = KMF_ERR_BAD_KEY_FORMAT; 24023089Swyllys goto cleanup; 24033089Swyllys } 24043089Swyllys pKeyParts[KMF_RSA_MODULUS].Data = (uchar_t *)Mod->bv_val; 24053089Swyllys pKeyParts[KMF_RSA_MODULUS].Length = Mod->bv_len; 24063089Swyllys pKeyParts[KMF_RSA_PUBLIC_EXPONENT].Data = 24073089Swyllys (uchar_t *)Exp->bv_val; 24083089Swyllys pKeyParts[KMF_RSA_PUBLIC_EXPONENT].Length = Exp->bv_len; 24093089Swyllys *uNumKeyParts = KMF_NUMBER_RSA_PUBLIC_KEY_PARTS; 24103089Swyllys 24113089Swyllys free(Mod); 24123089Swyllys free(Exp); 24133089Swyllys break; 24143089Swyllys default: 24153089Swyllys return (KMF_ERR_BAD_PARAMETER); 24163089Swyllys } 24173089Swyllys cleanup: 24183089Swyllys if (ret != KMF_OK) { 24193089Swyllys int i; 24203089Swyllys for (i = 0; i < *uNumKeyParts; i++) 24213089Swyllys free_data(&pKeyParts[i]); 24223089Swyllys } 24233089Swyllys if (asn1 != NULL) { 24243089Swyllys kmfber_free(asn1, 1); 24253089Swyllys } 24263089Swyllys 24273089Swyllys return (ret); 24283089Swyllys } 2429