From ab6e3fce040f9ad27cbce44e9038a24f15b601c8 Mon Sep 17 00:00:00 2001 From: Matthieu Patou Date: Sun, 15 Aug 2010 18:31:28 +0400 Subject: s4:heimdal: import lorikeet-heimdal-201009250123 (commit 42cabfb5b683dbcb97d583c397b897507689e382) I based this on Matthieu's import of lorikeet-heimdal, and then updated it to this commit. Andrew Bartlett --- source4/heimdal/lib/hx509/ca.c | 103 +++++++++++++--- source4/heimdal/lib/hx509/cert.c | 111 +++++++++++++++--- source4/heimdal/lib/hx509/char_map.h | 45 +++++++ source4/heimdal/lib/hx509/cms.c | 53 ++++++--- source4/heimdal/lib/hx509/crypto.c | 219 +++++++++++++++++------------------ source4/heimdal/lib/hx509/hx509.h | 7 ++ source4/heimdal/lib/hx509/ks_p11.c | 3 +- source4/heimdal/lib/hx509/name.c | 79 ++++++++----- source4/heimdal/lib/hx509/req.c | 6 +- source4/heimdal/lib/hx509/sel.c | 1 + 10 files changed, 431 insertions(+), 196 deletions(-) create mode 100644 source4/heimdal/lib/hx509/char_map.h (limited to 'source4/heimdal/lib/hx509') diff --git a/source4/heimdal/lib/hx509/ca.c b/source4/heimdal/lib/hx509/ca.c index 8ec6eae22a..492064d86d 100644 --- a/source4/heimdal/lib/hx509/ca.c +++ b/source4/heimdal/lib/hx509/ca.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan + * Copyright (c) 2006 - 2010 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -53,11 +53,15 @@ struct hx509_ca_tbs { unsigned int key:1; unsigned int serial:1; unsigned int domaincontroller:1; + unsigned int xUniqueID:1; } flags; time_t notBefore; time_t notAfter; int pathLenConstraint; /* both for CA and Proxy */ CRLDistributionPoints crldp; + heim_bit_string subjectUniqueID; + heim_bit_string issuerUniqueID; + }; /** @@ -80,15 +84,6 @@ hx509_ca_tbs_init(hx509_context context, hx509_ca_tbs *tbs) if (*tbs == NULL) return ENOMEM; - (*tbs)->subject = NULL; - (*tbs)->san.len = 0; - (*tbs)->san.val = NULL; - (*tbs)->eku.len = 0; - (*tbs)->eku.val = NULL; - (*tbs)->pathLenConstraint = 0; - (*tbs)->crldp.len = 0; - (*tbs)->crldp.val = NULL; - return 0; } @@ -111,7 +106,8 @@ hx509_ca_tbs_free(hx509_ca_tbs *tbs) free_ExtKeyUsage(&(*tbs)->eku); der_free_heim_integer(&(*tbs)->serial); free_CRLDistributionPoints(&(*tbs)->crldp); - + der_free_bit_string(&(*tbs)->subjectUniqueID); + der_free_bit_string(&(*tbs)->issuerUniqueID); hx509_name_free(&(*tbs)->subject); memset(*tbs, 0, sizeof(**tbs)); @@ -485,7 +481,8 @@ hx509_ca_tbs_add_crl_dp_uri(hx509_context context, name.u.fullName.val = &gn; gn.element = choice_GeneralName_uniformResourceIdentifier; - gn.u.uniformResourceIdentifier = rk_UNCONST(uri); + gn.u.uniformResourceIdentifier.data = rk_UNCONST(uri); + gn.u.uniformResourceIdentifier.length = strlen(uri); ASN1_MALLOC_ENCODE(DistributionPointName, dp.distributionPoint->data, @@ -785,7 +782,8 @@ hx509_ca_tbs_add_san_hostname(hx509_context context, memset(&gn, 0, sizeof(gn)); gn.element = choice_GeneralName_dNSName; - gn.u.dNSName = rk_UNCONST(dnsname); + gn.u.dNSName.data = rk_UNCONST(dnsname); + gn.u.dNSName.length = strlen(dnsname); return add_GeneralNames(&tbs->san, &gn); } @@ -812,7 +810,8 @@ hx509_ca_tbs_add_san_rfc822name(hx509_context context, memset(&gn, 0, sizeof(gn)); gn.element = choice_GeneralName_rfc822Name; - gn.u.rfc822Name = rk_UNCONST(rfc822Name); + gn.u.rfc822Name.data = rk_UNCONST(rfc822Name); + gn.u.rfc822Name.length = strlen(rfc822Name); return add_GeneralNames(&tbs->san, &gn); } @@ -839,6 +838,50 @@ hx509_ca_tbs_set_subject(hx509_context context, return hx509_name_copy(context, subject, &tbs->subject); } +/** + * Set the issuerUniqueID and subjectUniqueID + * + * These are only supposed to be used considered with version 2 + * certificates, replaced by the two extensions SubjectKeyIdentifier + * and IssuerKeyIdentifier. This function is to allow application + * using legacy protocol to issue them. + * + * @param context A hx509 context. + * @param tbs object to be signed. + * @param issuerUniqueID to be set + * @param subjectUniqueID to be set + * + * @return An hx509 error code, see hx509_get_error_string(). + * + * @ingroup hx509_ca + */ + +int +hx509_ca_tbs_set_unique(hx509_context context, + hx509_ca_tbs tbs, + const heim_bit_string *subjectUniqueID, + const heim_bit_string *issuerUniqueID) +{ + int ret; + + der_free_bit_string(&tbs->subjectUniqueID); + der_free_bit_string(&tbs->issuerUniqueID); + + if (subjectUniqueID) { + ret = der_copy_bit_string(subjectUniqueID, &tbs->subjectUniqueID); + if (ret) + return ret; + } + + if (issuerUniqueID) { + ret = der_copy_bit_string(issuerUniqueID, &tbs->issuerUniqueID); + if (ret) + return ret; + } + + return 0; +} + /** * Expand the the subject name in the to-be-signed certificate object * using hx509_name_expand(). @@ -861,6 +904,10 @@ hx509_ca_tbs_subject_expand(hx509_context context, return hx509_name_expand(context, tbs->subject, env); } +/* + * + */ + static int add_extension(hx509_context context, TBSCertificate *tbsc, @@ -1090,7 +1137,35 @@ ca_sign(hx509_context context, goto out; } /* issuerUniqueID [1] IMPLICIT BIT STRING OPTIONAL */ + if (tbs->issuerUniqueID.length) { + tbsc->issuerUniqueID = calloc(1, sizeof(*tbsc->issuerUniqueID)); + if (tbsc->issuerUniqueID == NULL) { + ret = ENOMEM; + hx509_set_error_string(context, 0, ret, "Out of memory"); + goto out; + } + ret = der_copy_bit_string(&tbs->issuerUniqueID, tbsc->issuerUniqueID); + if (ret) { + hx509_set_error_string(context, 0, ret, "Out of memory"); + goto out; + } + } /* subjectUniqueID [2] IMPLICIT BIT STRING OPTIONAL */ + if (tbs->subjectUniqueID.length) { + tbsc->subjectUniqueID = calloc(1, sizeof(*tbsc->subjectUniqueID)); + if (tbsc->subjectUniqueID == NULL) { + ret = ENOMEM; + hx509_set_error_string(context, 0, ret, "Out of memory"); + goto out; + } + + ret = der_copy_bit_string(&tbs->subjectUniqueID, tbsc->subjectUniqueID); + if (ret) { + hx509_set_error_string(context, 0, ret, "Out of memory"); + goto out; + } + } + /* extensions [3] EXPLICIT Extensions OPTIONAL */ tbsc->extensions = calloc(1, sizeof(*tbsc->extensions)); if (tbsc->extensions == NULL) { diff --git a/source4/heimdal/lib/hx509/cert.c b/source4/heimdal/lib/hx509/cert.c index 4783edd681..93a172e553 100644 --- a/source4/heimdal/lib/hx509/cert.c +++ b/source4/heimdal/lib/hx509/cert.c @@ -1510,6 +1510,65 @@ hx509_cert_get_SPKI_AlgorithmIdentifier(hx509_context context, return ret; } +static int +get_x_unique_id(hx509_context context, const char *name, + const heim_bit_string *cert, heim_bit_string *subject) +{ + int ret; + + if (cert == NULL) { + ret = HX509_EXTENSION_NOT_FOUND; + hx509_set_error_string(context, 0, ret, "%s unique id doesn't exists", name); + return ret; + } + ret = der_copy_bit_string(cert, subject); + if (ret) { + hx509_set_error_string(context, 0, ret, "malloc out of memory", name); + return ret; + } + return 0; +} + +/** + * Get a copy of the Issuer Unique ID + * + * @param context a hx509_context + * @param p a hx509 certificate + * @param issuer the issuer id returned, free with der_free_bit_string() + * + * @return An hx509 error code, see hx509_get_error_string(). The + * error code HX509_EXTENSION_NOT_FOUND is returned if the certificate + * doesn't have a issuerUniqueID + * + * @ingroup hx509_cert + */ + +int +hx509_cert_get_issuer_unique_id(hx509_context context, hx509_cert p, heim_bit_string *issuer) +{ + return get_x_unique_id(context, "issuer", p->data->tbsCertificate.issuerUniqueID, issuer); +} + +/** + * Get a copy of the Subect Unique ID + * + * @param context a hx509_context + * @param p a hx509 certificate + * @param subject the subject id returned, free with der_free_bit_string() + * + * @return An hx509 error code, see hx509_get_error_string(). The + * error code HX509_EXTENSION_NOT_FOUND is returned if the certificate + * doesn't have a subjectUniqueID + * + * @ingroup hx509_cert + */ + +int +hx509_cert_get_subject_unique_id(hx509_context context, hx509_cert p, heim_bit_string *subject) +{ + return get_x_unique_id(context, "subject", p->data->tbsCertificate.subjectUniqueID, subject); +} + hx509_private_key _hx509_cert_private_key(hx509_cert p) @@ -1696,19 +1755,20 @@ match_general_name(const GeneralName *c, const GeneralName *n, int *match) case choice_GeneralName_rfc822Name: { const char *s; size_t len1, len2; - s = strchr(c->u.rfc822Name, '@'); + s = memchr(c->u.rfc822Name.data, '@', c->u.rfc822Name.length); if (s) { - if (strcasecmp(c->u.rfc822Name, n->u.rfc822Name) != 0) + if (der_printable_string_cmp(&c->u.rfc822Name, &n->u.rfc822Name) != 0) return HX509_NAME_CONSTRAINT_ERROR; } else { - s = strchr(n->u.rfc822Name, '@'); + s = memchr(n->u.rfc822Name.data, '@', n->u.rfc822Name.length); if (s == NULL) return HX509_NAME_CONSTRAINT_ERROR; - len1 = strlen(c->u.rfc822Name); - len2 = strlen(s + 1); + len1 = c->u.rfc822Name.length; + len2 = n->u.rfc822Name.length - + (s - ((char *)n->u.rfc822Name.data)); if (len1 > len2) return HX509_NAME_CONSTRAINT_ERROR; - if (strcasecmp(s + 1 + len2 - len1, c->u.rfc822Name) != 0) + if (memcmp(s + 1 + len2 - len1, c->u.rfc822Name.data, len1) != 0) return HX509_NAME_CONSTRAINT_ERROR; if (len1 < len2 && s[len2 - len1 + 1] != '.') return HX509_NAME_CONSTRAINT_ERROR; @@ -1718,14 +1778,16 @@ match_general_name(const GeneralName *c, const GeneralName *n, int *match) } case choice_GeneralName_dNSName: { size_t lenc, lenn; + char *ptr; - lenc = strlen(c->u.dNSName); - lenn = strlen(n->u.dNSName); + lenc = c->u.dNSName.length; + lenn = n->u.dNSName.length; if (lenc > lenn) return HX509_NAME_CONSTRAINT_ERROR; - if (strcasecmp(&n->u.dNSName[lenn - lenc], c->u.dNSName) != 0) + ptr = n->u.dNSName.data; + if (memcmp(&ptr[lenn - lenc], c->u.dNSName.data, lenc) != 0) return HX509_NAME_CONSTRAINT_ERROR; - if (lenc != lenn && n->u.dNSName[lenn - lenc - 1] != '.') + if (lenn != lenc && ptr[lenn - lenc - 1] != '.') return HX509_NAME_CONSTRAINT_ERROR; *match = 1; return 0; @@ -2405,12 +2467,17 @@ hx509_verify_hostname(hx509_context context, for (j = 0; j < san.len; j++) { switch (san.val[j].element) { - case choice_GeneralName_dNSName: - if (strcasecmp(san.val[j].u.dNSName, hostname) == 0) { + case choice_GeneralName_dNSName: { + heim_printable_string hn; + hn.data = rk_UNCONST(hostname); + hn.length = strlen(hostname); + + if (der_printable_string_cmp(&san.val[j].u.dNSName, &hn) == 0) { free_GeneralNames(&san); return 0; } break; + } default: break; } @@ -2428,14 +2495,24 @@ hx509_verify_hostname(hx509_context context, if (der_heim_oid_cmp(&n->type, &asn1_oid_id_at_commonName) == 0) { DirectoryString *ds = &n->value; switch (ds->element) { - case choice_DirectoryString_printableString: - if (strcasecmp(ds->u.printableString, hostname) == 0) + case choice_DirectoryString_printableString: { + heim_printable_string hn; + hn.data = rk_UNCONST(hostname); + hn.length = strlen(hostname); + + if (der_printable_string_cmp(&ds->u.printableString, &hn) == 0) return 0; break; - case choice_DirectoryString_ia5String: - if (strcasecmp(ds->u.ia5String, hostname) == 0) - return 0; + } + case choice_DirectoryString_ia5String: { + heim_ia5_string hn; + hn.data = rk_UNCONST(hostname); + hn.length = strlen(hostname); + + if (der_ia5_string_cmp(&ds->u.ia5String, &hn) == 0) + return 0; break; + } case choice_DirectoryString_utf8String: if (strcasecmp(ds->u.utf8String, hostname) == 0) return 0; diff --git a/source4/heimdal/lib/hx509/char_map.h b/source4/heimdal/lib/hx509/char_map.h new file mode 100644 index 0000000000..d2b39d041f --- /dev/null +++ b/source4/heimdal/lib/hx509/char_map.h @@ -0,0 +1,45 @@ +#define Q_CONTROL_CHAR 1 +#define Q_PRINTABLE 2 +#define Q_RFC2253_QUOTE_FIRST 4 +#define Q_RFC2253_QUOTE_LAST 8 +#define Q_RFC2253_QUOTE 16 +#define Q_RFC2253_HEX 32 + +#define Q_RFC2253 (Q_RFC2253_QUOTE_FIRST|Q_RFC2253_QUOTE_LAST|Q_RFC2253_QUOTE|Q_RFC2253_HEX) + + + +unsigned char char_map[] = { + 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , + 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , + 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , + 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , + 0x06 , 0x00 , 0x00 , 0x10 , 0x00 , 0x00 , 0x00 , 0x00 , + 0x00 , 0x00 , 0x00 , 0x12 , 0x12 , 0x02 , 0x02 , 0x02 , + 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , + 0x02 , 0x02 , 0x02 , 0x10 , 0x10 , 0x12 , 0x10 , 0x02 , + 0x00 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , + 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , + 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , + 0x02 , 0x02 , 0x02 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , + 0x00 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , + 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , + 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , + 0x02 , 0x02 , 0x02 , 0x00 , 0x00 , 0x00 , 0x00 , 0x21 , + 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , + 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , + 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , + 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , + 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , + 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , + 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , + 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , + 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , + 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , + 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , + 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , + 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , + 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , + 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , + 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 +}; diff --git a/source4/heimdal/lib/hx509/cms.c b/source4/heimdal/lib/hx509/cms.c index 5506cee463..224c39086c 100644 --- a/source4/heimdal/lib/hx509/cms.c +++ b/source4/heimdal/lib/hx509/cms.c @@ -1170,6 +1170,7 @@ struct sigctx { heim_octet_string content; hx509_peer_info peer; int cmsidflag; + int leafonly; hx509_certs certs; hx509_certs anchors; hx509_certs pool; @@ -1360,7 +1361,7 @@ sig_process(hx509_context context, void *ctx, hx509_cert cert) if (sigctx->certs) { unsigned int i; - if (sigctx->pool) { + if (sigctx->pool && sigctx->leafonly == 0) { _hx509_calculate_path(context, HX509_CALCULATE_PATH_NO_ANCHOR, time(NULL), @@ -1415,6 +1416,12 @@ cert_process(hx509_context context, void *ctx, hx509_cert cert) return ret; } +static int +cmp_AlgorithmIdentifier(const AlgorithmIdentifier *p, const AlgorithmIdentifier *q) +{ + return der_heim_oid_cmp(&p->algorithm, &q->algorithm); +} + int hx509_cms_create_signed(hx509_context context, int flags, @@ -1427,7 +1434,7 @@ hx509_cms_create_signed(hx509_context context, hx509_certs pool, heim_octet_string *signed_data) { - unsigned int i; + unsigned int i, j; hx509_name name; int ret; size_t size; @@ -1454,9 +1461,22 @@ hx509_cms_create_signed(hx509_context context, else sigctx.cmsidflag = CMS_ID_SKI; - ret = hx509_certs_init(context, "MEMORY:certs", 0, NULL, &sigctx.certs); - if (ret) - return ret; + /** + * Use HX509_CMS_SIGNATURE_LEAF_ONLY to only request leaf + * certificates to be added to the SignedData. + */ + sigctx.leafonly = (flags & HX509_CMS_SIGNATURE_LEAF_ONLY) ? 1 : 0; + + /** + * Use HX509_CMS_NO_CERTS to make the SignedData contain no + * certificates, overrides HX509_CMS_SIGNATURE_LEAF_ONLY. + */ + + if ((flags & HX509_CMS_SIGNATURE_NO_CERTS) == 0) { + ret = hx509_certs_init(context, "MEMORY:certs", 0, NULL, &sigctx.certs); + if (ret) + return ret; + } sigctx.anchors = anchors; sigctx.pool = pool; @@ -1497,22 +1517,19 @@ hx509_cms_create_signed(hx509_context context, } if (sigctx.sd.signerInfos.len) { - ALLOC_SEQ(&sigctx.sd.digestAlgorithms, sigctx.sd.signerInfos.len); - if (sigctx.sd.digestAlgorithms.val == NULL) { - ret = ENOMEM; - hx509_clear_error_string(context); - goto out; - } - - /* XXX remove dups */ for (i = 0; i < sigctx.sd.signerInfos.len; i++) { AlgorithmIdentifier *di = &sigctx.sd.signerInfos.val[i].digestAlgorithm; - ret = copy_AlgorithmIdentifier(di, - &sigctx.sd.digestAlgorithms.val[i]); - if (ret) { - hx509_clear_error_string(context); - goto out; + + for (j = 0; j < sigctx.sd.digestAlgorithms.len; j++) + if (cmp_AlgorithmIdentifier(di, &sigctx.sd.digestAlgorithms.val[j]) == 0) + break; + if (j < sigctx.sd.digestAlgorithms.len) { + ret = add_DigestAlgorithmIdentifiers(&sigctx.sd.digestAlgorithms, di); + if (ret) { + hx509_clear_error_string(context); + goto out; + } } } } diff --git a/source4/heimdal/lib/hx509/crypto.c b/source4/heimdal/lib/hx509/crypto.c index 77be4413ac..c2e5e70748 100644 --- a/source4/heimdal/lib/hx509/crypto.c +++ b/source4/heimdal/lib/hx509/crypto.c @@ -149,11 +149,6 @@ const AlgorithmIdentifier _hx509_signature_md5_data = { { 6, rk_UNCONST(md5_oid_tree) }, rk_UNCONST(&null_entry_oid) }; -static const unsigned md2_oid_tree[] = { 1, 2, 840, 113549, 2, 2 }; -const AlgorithmIdentifier _hx509_signature_md2_data = { - { 6, rk_UNCONST(md2_oid_tree) }, rk_UNCONST(&null_entry_oid) -}; - static const unsigned ecPublicKey[] ={ 1, 2, 840, 10045, 2, 1 }; const AlgorithmIdentifier _hx509_signature_ecPublicKey = { { 6, rk_UNCONST(ecPublicKey) }, NULL @@ -194,11 +189,6 @@ const AlgorithmIdentifier _hx509_signature_rsa_with_md5_data = { { 7, rk_UNCONST(rsa_with_md5_oid) }, NULL }; -static const unsigned rsa_with_md2_oid[] ={ 1, 2, 840, 113549, 1, 1, 2 }; -const AlgorithmIdentifier _hx509_signature_rsa_with_md2_data = { - { 7, rk_UNCONST(rsa_with_md2_oid) }, NULL -}; - static const unsigned rsa_oid[] ={ 1, 2, 840, 113549, 1, 1, 1 }; const AlgorithmIdentifier _hx509_signature_rsa_data = { { 7, rk_UNCONST(rsa_oid) }, NULL @@ -283,11 +273,11 @@ heim_oid2ecnid(heim_oid *oid) * Now map to openssl OID fun */ - if (der_heim_oid_cmp(oid, &asn1_oid_id_ec_group_secp256r1) == 0) + if (der_heim_oid_cmp(oid, ASN1_OID_ID_EC_GROUP_SECP256R1) == 0) return NID_X9_62_prime256v1; - else if (der_heim_oid_cmp(oid, &asn1_oid_id_ec_group_secp160r1) == 0) + else if (der_heim_oid_cmp(oid, ASN1_OID_ID_EC_GROUP_SECP160R1) == 0) return NID_secp160r1; - else if (der_heim_oid_cmp(oid, &asn1_oid_id_ec_group_secp160r2) == 0) + else if (der_heim_oid_cmp(oid, ASN1_OID_ID_EC_GROUP_SECP160R2) == 0) return NID_secp160r2; return -1; @@ -370,7 +360,7 @@ ecdsa_verify_signature(hx509_context context, /* set up EC KEY */ spi = &signer->tbsCertificate.subjectPublicKeyInfo; - if (der_heim_oid_cmp(&spi->algorithm.algorithm, &asn1_oid_id_ecPublicKey) != 0) + if (der_heim_oid_cmp(&spi->algorithm.algorithm, ASN1_OID_ID_ECPUBLICKEY) != 0) return HX509_CRYPTO_SIG_INVALID_FORMAT; #ifdef HAVE_OPENSSL @@ -431,7 +421,7 @@ ecdsa_create_signature(hx509_context context, unsigned int siglen; int ret; - if (signer->ops && der_heim_oid_cmp(signer->ops->key_oid, &asn1_oid_id_ecPublicKey) != 0) + if (signer->ops && der_heim_oid_cmp(signer->ops->key_oid, ASN1_OID_ID_ECPUBLICKEY) != 0) _hx509_abort("internal error passing private key to wrong ops"); sig_oid = sig_alg->sig_oid; @@ -661,7 +651,7 @@ rsa_create_signature(hx509_context context, size_t size; int ret; - if (signer->ops && der_heim_oid_cmp(signer->ops->key_oid, &asn1_oid_id_pkcs1_rsaEncryption) != 0) + if (signer->ops && der_heim_oid_cmp(signer->ops->key_oid, ASN1_OID_ID_PKCS1_RSAENCRYPTION) != 0) return HX509_ALG_NOT_SUPP; if (alg) @@ -669,19 +659,19 @@ rsa_create_signature(hx509_context context, else sig_oid = signer->signature_alg; - if (der_heim_oid_cmp(sig_oid, &asn1_oid_id_pkcs1_sha256WithRSAEncryption) == 0) { + if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_SHA256WITHRSAENCRYPTION) == 0) { digest_alg = hx509_signature_sha256(); - } else if (der_heim_oid_cmp(sig_oid, &asn1_oid_id_pkcs1_sha1WithRSAEncryption) == 0) { + } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_SHA1WITHRSAENCRYPTION) == 0) { digest_alg = hx509_signature_sha1(); - } else if (der_heim_oid_cmp(sig_oid, &asn1_oid_id_pkcs1_md5WithRSAEncryption) == 0) { + } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_MD5WITHRSAENCRYPTION) == 0) { digest_alg = hx509_signature_md5(); - } else if (der_heim_oid_cmp(sig_oid, &asn1_oid_id_pkcs1_md5WithRSAEncryption) == 0) { + } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_MD5WITHRSAENCRYPTION) == 0) { digest_alg = hx509_signature_md5(); - } else if (der_heim_oid_cmp(sig_oid, &asn1_oid_id_dsa_with_sha1) == 0) { + } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_DSA_WITH_SHA1) == 0) { digest_alg = hx509_signature_sha1(); - } else if (der_heim_oid_cmp(sig_oid, &asn1_oid_id_pkcs1_rsaEncryption) == 0) { + } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_RSAENCRYPTION) == 0) { digest_alg = hx509_signature_sha1(); - } else if (der_heim_oid_cmp(sig_oid, &asn1_oid_id_heim_rsa_pkcs1_x509) == 0) { + } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_HEIM_RSA_PKCS1_X509) == 0) { digest_alg = NULL; } else return HX509_ALG_NOT_SUPP; @@ -767,7 +757,7 @@ rsa_private_key_import(hx509_context context, "Failed to parse RSA key"); return HX509_PARSING_KEY_FAILED; } - private_key->signature_alg = &asn1_oid_id_pkcs1_sha1WithRSAEncryption; + private_key->signature_alg = ASN1_OID_ID_PKCS1_SHA1WITHRSAENCRYPTION; return 0; } @@ -790,7 +780,7 @@ rsa_private_key2SPKI(hx509_context context, } spki->subjectPublicKey.length = len * 8; - ret = set_digest_alg(&spki->algorithm, &asn1_oid_id_pkcs1_rsaEncryption, + ret = set_digest_alg(&spki->algorithm, ASN1_OID_ID_PKCS1_RSAENCRYPTION, "\x05\x00", 2); if (ret) { hx509_set_error_string(context, 0, ret, "malloc - out of memory"); @@ -844,7 +834,7 @@ rsa_generate_private_key(hx509_context context, "Failed to generate RSA key"); return HX509_PARSING_KEY_FAILED; } - private_key->signature_alg = &asn1_oid_id_pkcs1_sha1WithRSAEncryption; + private_key->signature_alg = ASN1_OID_ID_PKCS1_SHA1WITHRSAENCRYPTION; return 0; } @@ -900,7 +890,7 @@ rsa_get_internal(hx509_context context, static hx509_private_key_ops rsa_private_key_ops = { "RSA PRIVATE KEY", - &asn1_oid_id_pkcs1_rsaEncryption, + ASN1_OID_ID_PKCS1_RSAENCRYPTION, NULL, rsa_private_key2SPKI, rsa_private_key_export, @@ -973,7 +963,7 @@ ecdsa_private_key_import(hx509_context context, "Failed to parse EC private key"); return HX509_PARSING_KEY_FAILED; } - private_key->signature_alg = &asn1_oid_id_ecdsa_with_SHA256; + private_key->signature_alg = ASN1_OID_ID_ECDSA_WITH_SHA256; return 0; } @@ -997,7 +987,7 @@ ecdsa_get_internal(hx509_context context, static hx509_private_key_ops ecdsa_private_key_ops = { "EC PRIVATE KEY", - &asn1_oid_id_ecPublicKey, + ASN1_OID_ID_ECPUBLICKEY, ecdsa_available, ecdsa_private_key2SPKI, ecdsa_private_key_export, @@ -1110,7 +1100,7 @@ dsa_parse_private_key(hx509_context context, d2i_DSAPrivateKey(NULL, &p, len); if (private_key->private_key.dsa == NULL) return EINVAL; - private_key->signature_alg = &asn1_oid_id_dsa_with_sha1; + private_key->signature_alg = ASN1_OID_ID_DSA_WITH_SHA1; return 0; /* else */ @@ -1197,9 +1187,9 @@ evp_md_verify_signature(hx509_context context, static const struct signature_alg ecdsa_with_sha256_alg = { "ecdsa-with-sha256", - &asn1_oid_id_ecdsa_with_SHA256, + ASN1_OID_ID_ECDSA_WITH_SHA256, &_hx509_signature_ecdsa_with_sha256_data, - &asn1_oid_id_ecPublicKey, + ASN1_OID_ID_ECPUBLICKEY, &_hx509_signature_sha256_data, PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|SELF_SIGNED_OK, 0, @@ -1211,9 +1201,9 @@ static const struct signature_alg ecdsa_with_sha256_alg = { static const struct signature_alg ecdsa_with_sha1_alg = { "ecdsa-with-sha1", - &asn1_oid_id_ecdsa_with_SHA1, + ASN1_OID_ID_ECDSA_WITH_SHA1, &_hx509_signature_ecdsa_with_sha1_data, - &asn1_oid_id_ecPublicKey, + ASN1_OID_ID_ECPUBLICKEY, &_hx509_signature_sha1_data, PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|SELF_SIGNED_OK, 0, @@ -1227,9 +1217,9 @@ static const struct signature_alg ecdsa_with_sha1_alg = { static const struct signature_alg heim_rsa_pkcs1_x509 = { "rsa-pkcs1-x509", - &asn1_oid_id_heim_rsa_pkcs1_x509, + ASN1_OID_ID_HEIM_RSA_PKCS1_X509, &_hx509_signature_rsa_pkcs1_x509_data, - &asn1_oid_id_pkcs1_rsaEncryption, + ASN1_OID_ID_PKCS1_RSAENCRYPTION, NULL, PROVIDE_CONF|REQUIRE_SIGNER|SIG_PUBLIC_SIG, 0, @@ -1240,9 +1230,9 @@ static const struct signature_alg heim_rsa_pkcs1_x509 = { static const struct signature_alg pkcs1_rsa_sha1_alg = { "rsa", - &asn1_oid_id_pkcs1_rsaEncryption, + ASN1_OID_ID_PKCS1_RSAENCRYPTION, &_hx509_signature_rsa_with_sha1_data, - &asn1_oid_id_pkcs1_rsaEncryption, + ASN1_OID_ID_PKCS1_RSAENCRYPTION, NULL, PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|SELF_SIGNED_OK, 0, @@ -1253,9 +1243,9 @@ static const struct signature_alg pkcs1_rsa_sha1_alg = { static const struct signature_alg rsa_with_sha256_alg = { "rsa-with-sha256", - &asn1_oid_id_pkcs1_sha256WithRSAEncryption, + ASN1_OID_ID_PKCS1_SHA256WITHRSAENCRYPTION, &_hx509_signature_rsa_with_sha256_data, - &asn1_oid_id_pkcs1_rsaEncryption, + ASN1_OID_ID_PKCS1_RSAENCRYPTION, &_hx509_signature_sha256_data, PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|SELF_SIGNED_OK, 0, @@ -1266,9 +1256,9 @@ static const struct signature_alg rsa_with_sha256_alg = { static const struct signature_alg rsa_with_sha1_alg = { "rsa-with-sha1", - &asn1_oid_id_pkcs1_sha1WithRSAEncryption, + ASN1_OID_ID_PKCS1_SHA1WITHRSAENCRYPTION, &_hx509_signature_rsa_with_sha1_data, - &asn1_oid_id_pkcs1_rsaEncryption, + ASN1_OID_ID_PKCS1_RSAENCRYPTION, &_hx509_signature_sha1_data, PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|SELF_SIGNED_OK, 0, @@ -1277,25 +1267,25 @@ static const struct signature_alg rsa_with_sha1_alg = { rsa_create_signature }; -static const struct signature_alg rsa_with_md5_alg = { - "rsa-with-md5", - &asn1_oid_id_pkcs1_md5WithRSAEncryption, - &_hx509_signature_rsa_with_md5_data, - &asn1_oid_id_pkcs1_rsaEncryption, - &_hx509_signature_md5_data, - PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG, - 1230739889, +static const struct signature_alg rsa_with_sha1_alg_secsig = { + "rsa-with-sha1", + ASN1_OID_ID_SECSIG_SHA_1WITHRSAENCRYPTION, + &_hx509_signature_rsa_with_sha1_data, + ASN1_OID_ID_PKCS1_RSAENCRYPTION, + &_hx509_signature_sha1_data, + PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|SELF_SIGNED_OK, + 0, NULL, rsa_verify_signature, rsa_create_signature }; -static const struct signature_alg rsa_with_md2_alg = { - "rsa-with-md2", - &asn1_oid_id_pkcs1_md2WithRSAEncryption, - &_hx509_signature_rsa_with_md2_data, - &asn1_oid_id_pkcs1_rsaEncryption, - &_hx509_signature_md2_data, +static const struct signature_alg rsa_with_md5_alg = { + "rsa-with-md5", + ASN1_OID_ID_PKCS1_MD5WITHRSAENCRYPTION, + &_hx509_signature_rsa_with_md5_data, + ASN1_OID_ID_PKCS1_RSAENCRYPTION, + &_hx509_signature_md5_data, PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG, 1230739889, NULL, @@ -1305,9 +1295,9 @@ static const struct signature_alg rsa_with_md2_alg = { static const struct signature_alg dsa_sha1_alg = { "dsa-with-sha1", - &asn1_oid_id_dsa_with_sha1, + ASN1_OID_ID_DSA_WITH_SHA1, NULL, - &asn1_oid_id_dsa, + ASN1_OID_ID_DSA, &_hx509_signature_sha1_data, PROVIDE_CONF|REQUIRE_SIGNER|SIG_PUBLIC_SIG, 0, @@ -1318,7 +1308,7 @@ static const struct signature_alg dsa_sha1_alg = { static const struct signature_alg sha256_alg = { "sha-256", - &asn1_oid_id_sha256, + ASN1_OID_ID_SHA256, &_hx509_signature_sha256_data, NULL, NULL, @@ -1331,7 +1321,7 @@ static const struct signature_alg sha256_alg = { static const struct signature_alg sha1_alg = { "sha1", - &asn1_oid_id_secsig_sha_1, + ASN1_OID_ID_SECSIG_SHA_1, &_hx509_signature_sha1_data, NULL, NULL, @@ -1344,7 +1334,7 @@ static const struct signature_alg sha1_alg = { static const struct signature_alg md5_alg = { "rsa-md5", - &asn1_oid_id_rsa_digest_md5, + ASN1_OID_ID_RSA_DIGEST_MD5, &_hx509_signature_md5_data, NULL, NULL, @@ -1355,19 +1345,6 @@ static const struct signature_alg md5_alg = { NULL }; -static const struct signature_alg md2_alg = { - "rsa-md2", - &asn1_oid_id_rsa_digest_md2, - &_hx509_signature_md2_data, - NULL, - NULL, - SIG_DIGEST, - 0, - EVP_md2, - evp_md_verify_signature, - NULL -}; - /* * Order matter in this structure, "best" first for each "key * compatible" type (type is ECDSA, RSA, DSA, none, etc) @@ -1380,15 +1357,14 @@ static const struct signature_alg *sig_algs[] = { #endif &rsa_with_sha256_alg, &rsa_with_sha1_alg, + &rsa_with_sha1_alg_secsig, &pkcs1_rsa_sha1_alg, &rsa_with_md5_alg, - &rsa_with_md2_alg, &heim_rsa_pkcs1_x509, &dsa_sha1_alg, &sha256_alg, &sha1_alg, &md5_alg, - &md2_alg, NULL }; @@ -1641,7 +1617,7 @@ _hx509_public_encrypt(hx509_context context, ciphertext->length = ret; ciphertext->data = to; - ret = der_copy_oid(&asn1_oid_id_pkcs1_rsaEncryption, encryption_oid); + ret = der_copy_oid(ASN1_OID_ID_PKCS1_RSAENCRYPTION, encryption_oid); if (ret) { der_free_octet_string(ciphertext); hx509_set_error_string(context, 0, ENOMEM, "out of memory"); @@ -1750,7 +1726,7 @@ _hx509_generate_private_key_init(hx509_context context, { *ctx = NULL; - if (der_heim_oid_cmp(oid, &asn1_oid_id_pkcs1_rsaEncryption) != 0) { + if (der_heim_oid_cmp(oid, ASN1_OID_ID_PKCS1_RSAENCRYPTION) != 0) { hx509_set_error_string(context, 0, EINVAL, "private key not an RSA key"); return EINVAL; @@ -1844,10 +1820,6 @@ const AlgorithmIdentifier * hx509_signature_md5(void) { return &_hx509_signature_md5_data; } -const AlgorithmIdentifier * -hx509_signature_md2(void) -{ return &_hx509_signature_md2_data; } - const AlgorithmIdentifier * hx509_signature_ecPublicKey(void) { return &_hx509_signature_ecPublicKey; } @@ -1880,10 +1852,6 @@ const AlgorithmIdentifier * hx509_signature_rsa_with_md5(void) { return &_hx509_signature_rsa_with_md5_data; } -const AlgorithmIdentifier * -hx509_signature_rsa_with_md2(void) -{ return &_hx509_signature_rsa_with_md2_data; } - const AlgorithmIdentifier * hx509_signature_rsa(void) { return &_hx509_signature_rsa_data; } @@ -1961,11 +1929,11 @@ _hx509_private_key_free(hx509_private_key *key) if (--(*key)->ref > 0) return 0; - if ((*key)->ops && der_heim_oid_cmp((*key)->ops->key_oid, &asn1_oid_id_pkcs1_rsaEncryption) == 0) { + if ((*key)->ops && der_heim_oid_cmp((*key)->ops->key_oid, ASN1_OID_ID_PKCS1_RSAENCRYPTION) == 0) { if ((*key)->private_key.rsa) RSA_free((*key)->private_key.rsa); #ifdef HAVE_OPENSSL - } else if ((*key)->ops && der_heim_oid_cmp((*key)->ops->key_oid, &asn1_oid_id_ecPublicKey) == 0) { + } else if ((*key)->ops && der_heim_oid_cmp((*key)->ops->key_oid, ASN1_OID_ID_ECPUBLICKEY) == 0) { if ((*key)->private_key.ecdsa) EC_KEY_free((*key)->private_key.ecdsa); #endif @@ -1982,7 +1950,7 @@ _hx509_private_key_assign_rsa(hx509_private_key key, void *ptr) if (key->private_key.rsa) RSA_free(key->private_key.rsa); key->private_key.rsa = ptr; - key->signature_alg = &asn1_oid_id_pkcs1_sha1WithRSAEncryption; + key->signature_alg = ASN1_OID_ID_PKCS1_SHA1WITHRSAENCRYPTION; key->md = &pkcs1_rsa_sha1_alg; } @@ -2048,7 +2016,11 @@ struct hx509cipher { struct hx509_crypto_data { char *name; int flags; -#define ALLOW_WEAK 1 +#define ALLOW_WEAK 1 + +#define PADDING_NONE 2 +#define PADDING_PKCS7 4 +#define PADDING_FLAGS (2|4) const struct hx509cipher *cipher; const EVP_CIPHER *c; heim_octet_string key; @@ -2204,7 +2176,7 @@ static const struct hx509cipher ciphers[] = { { "rc2-cbc", CIPHER_WEAK, - &asn1_oid_id_pkcs3_rc2_cbc, + ASN1_OID_ID_PKCS3_RC2_CBC, NULL, EVP_rc2_cbc, CMSRC2CBCParam_get, @@ -2213,7 +2185,7 @@ static const struct hx509cipher ciphers[] = { { "rc2-cbc", CIPHER_WEAK, - &asn1_oid_id_rsadsi_rc2_cbc, + ASN1_OID_ID_RSADSI_RC2_CBC, NULL, EVP_rc2_cbc, CMSRC2CBCParam_get, @@ -2231,7 +2203,7 @@ static const struct hx509cipher ciphers[] = { { "des-ede3-cbc", 0, - &asn1_oid_id_pkcs3_des_ede3_cbc, + ASN1_OID_ID_PKCS3_DES_EDE3_CBC, NULL, EVP_des_ede3_cbc, CMSCBCParam_get, @@ -2240,7 +2212,7 @@ static const struct hx509cipher ciphers[] = { { "des-ede3-cbc", 0, - &asn1_oid_id_rsadsi_des_ede3_cbc, + ASN1_OID_ID_RSADSI_DES_EDE3_CBC, hx509_crypto_des_rsdi_ede3_cbc, EVP_des_ede3_cbc, CMSCBCParam_get, @@ -2249,7 +2221,7 @@ static const struct hx509cipher ciphers[] = { { "aes-128-cbc", 0, - &asn1_oid_id_aes_128_cbc, + ASN1_OID_ID_AES_128_CBC, hx509_crypto_aes128_cbc, EVP_aes_128_cbc, CMSCBCParam_get, @@ -2258,7 +2230,7 @@ static const struct hx509cipher ciphers[] = { { "aes-192-cbc", 0, - &asn1_oid_id_aes_192_cbc, + ASN1_OID_ID_AES_192_CBC, NULL, EVP_aes_192_cbc, CMSCBCParam_get, @@ -2267,7 +2239,7 @@ static const struct hx509cipher ciphers[] = { { "aes-256-cbc", 0, - &asn1_oid_id_aes_256_cbc, + ASN1_OID_ID_AES_256_CBC, hx509_crypto_aes256_cbc, EVP_aes_256_cbc, CMSCBCParam_get, @@ -2334,6 +2306,7 @@ hx509_crypto_init(hx509_context context, return ENOMEM; } + (*crypto)->flags = PADDING_PKCS7; (*crypto)->cipher = cipher; (*crypto)->c = (*cipher->evp_func)(); @@ -2379,6 +2352,23 @@ hx509_crypto_allow_weak(hx509_crypto crypto) crypto->flags |= ALLOW_WEAK; } +void +hx509_crypto_set_padding(hx509_crypto crypto, int padding_type) +{ + switch (padding_type) { + case HX509_CRYPTO_PADDING_PKCS7: + crypto->flags &= ~PADDING_FLAGS; + crypto->flags |= PADDING_PKCS7; + break; + case HX509_CRYPTO_PADDING_NONE: + crypto->flags &= ~PADDING_FLAGS; + crypto->flags |= PADDING_NONE; + break; + default: + _hx509_abort("Invalid padding"); + } +} + int hx509_crypto_set_key_data(hx509_crypto crypto, const void *data, size_t length) { @@ -2497,12 +2487,17 @@ hx509_crypto_encrypt(hx509_crypto crypto, goto out; } - if (EVP_CIPHER_block_size(crypto->c) == 1) { + assert(crypto->flags & PADDING_FLAGS); + if (crypto->flags & PADDING_NONE) { padsize = 0; - } else { - int bsize = EVP_CIPHER_block_size(crypto->c); - padsize = bsize - (length % bsize); + } else if (crypto->flags & PADDING_PKCS7) { + if (EVP_CIPHER_block_size(crypto->c) == 1) { + } else { + int bsize = EVP_CIPHER_block_size(crypto->c); + padsize = bsize - (length % bsize); + } } + (*ciphertext)->length = length + padsize; (*ciphertext)->data = malloc(length + padsize); if ((*ciphertext)->data == NULL) { @@ -2592,7 +2587,7 @@ hx509_crypto_decrypt(hx509_crypto crypto, } EVP_CIPHER_CTX_cleanup(&evp); - if (EVP_CIPHER_block_size(crypto->c) > 1) { + if ((crypto->flags & PADDING_PKCS7) && EVP_CIPHER_block_size(crypto->c) > 1) { int padsize; unsigned char *p; int j, bsize = EVP_CIPHER_block_size(crypto->c); @@ -2704,33 +2699,33 @@ find_string2key(const heim_oid *oid, const EVP_MD **md, PBE_string2key_func *s2k) { - if (der_heim_oid_cmp(oid, &asn1_oid_id_pbewithSHAAnd40BitRC2_CBC) == 0) { + if (der_heim_oid_cmp(oid, ASN1_OID_ID_PBEWITHSHAAND40BITRC2_CBC) == 0) { *c = EVP_rc2_40_cbc(); *md = EVP_sha1(); *s2k = PBE_string2key; return &asn1_oid_private_rc2_40; - } else if (der_heim_oid_cmp(oid, &asn1_oid_id_pbeWithSHAAnd128BitRC2_CBC) == 0) { + } else if (der_heim_oid_cmp(oid, ASN1_OID_ID_PBEWITHSHAAND128BITRC2_CBC) == 0) { *c = EVP_rc2_cbc(); *md = EVP_sha1(); *s2k = PBE_string2key; - return &asn1_oid_id_pkcs3_rc2_cbc; + return ASN1_OID_ID_PKCS3_RC2_CBC; #if 0 - } else if (der_heim_oid_cmp(oid, &asn1_oid_id_pbeWithSHAAnd40BitRC4) == 0) { + } else if (der_heim_oid_cmp(oid, ASN1_OID_ID_PBEWITHSHAAND40BITRC4) == 0) { *c = EVP_rc4_40(); *md = EVP_sha1(); *s2k = PBE_string2key; return NULL; - } else if (der_heim_oid_cmp(oid, &asn1_oid_id_pbeWithSHAAnd128BitRC4) == 0) { + } else if (der_heim_oid_cmp(oid, ASN1_OID_ID_PBEWITHSHAAND128BITRC4) == 0) { *c = EVP_rc4(); *md = EVP_sha1(); *s2k = PBE_string2key; - return &asn1_oid_id_pkcs3_rc4; + return ASN1_OID_ID_PKCS3_RC4; #endif - } else if (der_heim_oid_cmp(oid, &asn1_oid_id_pbeWithSHAAnd3_KeyTripleDES_CBC) == 0) { + } else if (der_heim_oid_cmp(oid, ASN1_OID_ID_PBEWITHSHAAND3_KEYTRIPLEDES_CBC) == 0) { *c = EVP_des_ede3_cbc(); *md = EVP_sha1(); *s2k = PBE_string2key; - return &asn1_oid_id_pkcs3_des_ede3_cbc; + return ASN1_OID_ID_PKCS3_DES_EDE3_CBC; } return NULL; @@ -2907,9 +2902,9 @@ match_keys_ec(hx509_cert c, hx509_private_key private_key) int _hx509_match_keys(hx509_cert c, hx509_private_key key) { - if (der_heim_oid_cmp(key->ops->key_oid, &asn1_oid_id_pkcs1_rsaEncryption) == 0) + if (der_heim_oid_cmp(key->ops->key_oid, ASN1_OID_ID_PKCS1_RSAENCRYPTION) == 0) return match_keys_rsa(c, key); - if (der_heim_oid_cmp(key->ops->key_oid, &asn1_oid_id_ecPublicKey) == 0) + if (der_heim_oid_cmp(key->ops->key_oid, ASN1_OID_ID_ECPUBLICKEY) == 0) return match_keys_ec(c, key); return 0; diff --git a/source4/heimdal/lib/hx509/hx509.h b/source4/heimdal/lib/hx509/hx509.h index 86aad7ec9c..b6eeac9d18 100644 --- a/source4/heimdal/lib/hx509/hx509.h +++ b/source4/heimdal/lib/hx509/hx509.h @@ -71,6 +71,11 @@ enum { HX509_VALIDATE_F_VERBOSE = 2 }; +enum { + HX509_CRYPTO_PADDING_PKCS7 = 0, + HX509_CRYPTO_PADDING_NONE = 1 +}; + struct hx509_cert_attribute_data { heim_oid oid; heim_octet_string data; @@ -157,6 +162,8 @@ typedef enum { #define HX509_CMS_SIGNATURE_DETACHED 0x01 #define HX509_CMS_SIGNATURE_ID_NAME 0x02 #define HX509_CMS_SIGNATURE_NO_SIGNER 0x04 +#define HX509_CMS_SIGNATURE_LEAF_ONLY 0x08 +#define HX509_CMS_SIGNATURE_NO_CERTS 0x10 /* hx509_verify_hostname nametype */ typedef enum { diff --git a/source4/heimdal/lib/hx509/ks_p11.c b/source4/heimdal/lib/hx509/ks_p11.c index 52697f834b..23f6a4826a 100644 --- a/source4/heimdal/lib/hx509/ks_p11.c +++ b/source4/heimdal/lib/hx509/ks_p11.c @@ -835,7 +835,7 @@ p11_init(hx509_context context, goto out; } - getFuncs = dlsym(p->dl_handle, "C_GetFunctionList"); + getFuncs = (CK_C_GetFunctionList) dlsym(p->dl_handle, "C_GetFunctionList"); if (getFuncs == NULL) { ret = HX509_PKCS11_LOAD; hx509_set_error_string(context, 0, ret, @@ -1139,7 +1139,6 @@ p11_printinfo(hx509_context context, MECHNAME(CKM_SHA256, "sha256"); MECHNAME(CKM_SHA_1, "sha1"); MECHNAME(CKM_MD5, "md5"); - MECHNAME(CKM_MD2, "md2"); MECHNAME(CKM_RIPEMD160, "ripemd-160"); MECHNAME(CKM_DES_ECB, "des-ecb"); MECHNAME(CKM_DES_CBC, "des-cbc"); diff --git a/source4/heimdal/lib/hx509/name.c b/source4/heimdal/lib/hx509/name.c index e795b1e44e..83b8f86d41 100644 --- a/source4/heimdal/lib/hx509/name.c +++ b/source4/heimdal/lib/hx509/name.c @@ -33,6 +33,7 @@ #include "hx_locl.h" #include +#include "char_map.h" /** * @page page_name PKIX/X.509 Names @@ -79,11 +80,11 @@ static const struct { }; static char * -quote_string(const char *f, size_t len, size_t *rlen) +quote_string(const char *f, size_t len, int flags, size_t *rlen) { size_t i, j, tolen; - const char *from = f; - char *to; + const unsigned char *from = (const unsigned char *)f; + unsigned char *to; tolen = len * 3 + 1; to = malloc(tolen); @@ -91,26 +92,29 @@ quote_string(const char *f, size_t len, size_t *rlen) return NULL; for (i = 0, j = 0; i < len; i++) { - if (from[i] == ' ' && i + 1 < len) + unsigned char map = char_map[from[i]] & flags; + if (i == 0 && (map & Q_RFC2253_QUOTE_FIRST)) { + to[j++] = '\\'; to[j++] = from[i]; - else if (from[i] == ',' || from[i] == '=' || from[i] == '+' || - from[i] == '<' || from[i] == '>' || from[i] == '#' || - from[i] == ';' || from[i] == ' ') - { + } else if ((i + 1) == len && (map & Q_RFC2253_QUOTE_LAST)) { + to[j++] = '\\'; to[j++] = from[i]; - } else if (((unsigned char)from[i]) >= 32 && ((unsigned char)from[i]) <= 127) { + } else if (map & Q_RFC2253_QUOTE) { + to[j++] = '\\'; to[j++] = from[i]; - } else { - int l = snprintf(&to[j], tolen - j - 1, + } else if (map & Q_RFC2253_HEX) { + int l = snprintf((char *)&to[j], tolen - j - 1, "#%02x", (unsigned char)from[i]); j += l; + } else { + to[j++] = from[i]; } } to[j] = '\0'; assert(j < tolen); *rlen = j; - return to; + return (char *)to; } @@ -121,7 +125,7 @@ append_string(char **str, size_t *total_len, const char *ss, char *s, *qs; if (quote) - qs = quote_string(ss, len, &len); + qs = quote_string(ss, len, Q_RFC2253, &len); else qs = rk_UNCONST(ss); @@ -203,7 +207,7 @@ _hx509_Name_to_string(const Name *n, char **str) return ENOMEM; for (i = n->u.rdnSequence.len - 1 ; i >= 0 ; i--) { - int len; + size_t len; for (j = 0; j < n->u.rdnSequence.val[i].len; j++) { DirectoryString *ds = &n->u.rdnSequence.val[i].val[j].value; @@ -214,13 +218,16 @@ _hx509_Name_to_string(const Name *n, char **str) switch(ds->element) { case choice_DirectoryString_ia5String: - ss = ds->u.ia5String; + ss = ds->u.ia5String.data; + len = ds->u.ia5String.length; break; case choice_DirectoryString_printableString: - ss = ds->u.printableString; + ss = ds->u.printableString.data; + len = ds->u.printableString.length; break; case choice_DirectoryString_utf8String: ss = ds->u.utf8String; + len = strlen(ss); break; case choice_DirectoryString_bmpString: { const uint16_t *bmp = ds->u.bmpString.data; @@ -240,10 +247,12 @@ _hx509_Name_to_string(const Name *n, char **str) return ret; } ss[k] = '\0'; + len = k; break; } case choice_DirectoryString_teletexString: ss = ds->u.teletexString; + len = strlen(ss); break; case choice_DirectoryString_universalString: { const uint32_t *uni = ds->u.universalString.data; @@ -263,6 +272,7 @@ _hx509_Name_to_string(const Name *n, char **str) return ret; } ss[k] = '\0'; + len = k; break; } default: @@ -272,10 +282,9 @@ _hx509_Name_to_string(const Name *n, char **str) append_string(str, &total_len, oidname, strlen(oidname), 0); free(oidname); append_string(str, &total_len, "=", 1, 0); - len = strlen(ss); append_string(str, &total_len, ss, len, 1); - if (ds->element == choice_DirectoryString_universalString || - ds->element == choice_DirectoryString_bmpString) + if (ds->element == choice_DirectoryString_bmpString || + ds->element == choice_DirectoryString_universalString) { free(ss); } @@ -319,7 +328,7 @@ _hx509_Name_to_string(const Name *n, char **str) static int dsstringprep(const DirectoryString *ds, uint32_t **rname, size_t *rlen) { - wind_profile_flags flags = 0; + wind_profile_flags flags; size_t i, len; int ret; uint32_t *name; @@ -329,22 +338,28 @@ dsstringprep(const DirectoryString *ds, uint32_t **rname, size_t *rlen) switch(ds->element) { case choice_DirectoryString_ia5String: - COPYCHARARRAY(ds, ia5String, len, name); + flags = WIND_PROFILE_LDAP; + COPYVOIDARRAY(ds, ia5String, len, name); break; case choice_DirectoryString_printableString: - flags = WIND_PROFILE_LDAP_CASE_EXACT_ATTRIBUTE; - COPYCHARARRAY(ds, printableString, len, name); + flags = WIND_PROFILE_LDAP; + flags |= WIND_PROFILE_LDAP_CASE_EXACT_ATTRIBUTE; + COPYVOIDARRAY(ds, printableString, len, name); break; case choice_DirectoryString_teletexString: + flags = WIND_PROFILE_LDAP_CASE; COPYCHARARRAY(ds, teletexString, len, name); break; case choice_DirectoryString_bmpString: + flags = WIND_PROFILE_LDAP; COPYVALARRAY(ds, bmpString, len, name); break; case choice_DirectoryString_universalString: + flags = WIND_PROFILE_LDAP; COPYVALARRAY(ds, universalString, len, name); break; case choice_DirectoryString_utf8String: + flags = WIND_PROFILE_LDAP; ret = wind_utf8ucs4_length(ds->u.utf8String, &len); if (ret) return ret; @@ -367,8 +382,7 @@ dsstringprep(const DirectoryString *ds, uint32_t **rname, size_t *rlen) *rlen = *rlen * 2; *rname = malloc(*rlen * sizeof((*rname)[0])); - ret = wind_stringprep(name, len, *rname, rlen, - WIND_PROFILE_LDAP|flags); + ret = wind_stringprep(name, len, *rname, rlen, flags); if (ret == WIND_ERR_OVERRUN) { free(*rname); *rname = NULL; @@ -934,12 +948,14 @@ hx509_general_name_unparse(GeneralName *name, char **str) break; } case choice_GeneralName_rfc822Name: - strpool = rk_strpoolprintf(strpool, "rfc822Name: %s\n", - name->u.rfc822Name); + strpool = rk_strpoolprintf(strpool, "rfc822Name: %.*s\n", + (int)name->u.rfc822Name.length, + (char *)name->u.rfc822Name.data); break; case choice_GeneralName_dNSName: - strpool = rk_strpoolprintf(strpool, "dNSName: %s\n", - name->u.dNSName); + strpool = rk_strpoolprintf(strpool, "dNSName: %.*s\n", + (int)name->u.dNSName.length, + (char *)name->u.dNSName.data); break; case choice_GeneralName_directoryName: { Name dir; @@ -956,8 +972,9 @@ hx509_general_name_unparse(GeneralName *name, char **str) break; } case choice_GeneralName_uniformResourceIdentifier: - strpool = rk_strpoolprintf(strpool, "URI: %s", - name->u.uniformResourceIdentifier); + strpool = rk_strpoolprintf(strpool, "URI: %.*s", + (int)name->u.uniformResourceIdentifier.length, + (char *)name->u.uniformResourceIdentifier.data); break; case choice_GeneralName_iPAddress: { unsigned char *a = name->u.iPAddress.data; diff --git a/source4/heimdal/lib/hx509/req.c b/source4/heimdal/lib/hx509/req.c index 0d174e0cec..917f08891b 100644 --- a/source4/heimdal/lib/hx509/req.c +++ b/source4/heimdal/lib/hx509/req.c @@ -143,7 +143,8 @@ _hx509_request_add_dns_name(hx509_context context, memset(&name, 0, sizeof(name)); name.element = choice_GeneralName_dNSName; - name.u.dNSName = rk_UNCONST(hostname); + name.u.dNSName.data = rk_UNCONST(hostname); + name.u.dNSName.length = strlen(hostname); return add_GeneralNames(&req->san, &name); } @@ -157,7 +158,8 @@ _hx509_request_add_email(hx509_context context, memset(&name, 0, sizeof(name)); name.element = choice_GeneralName_rfc822Name; - name.u.dNSName = rk_UNCONST(email); + name.u.dNSName.data = rk_UNCONST(email); + name.u.dNSName.length = strlen(email); return add_GeneralNames(&req->san, &name); } diff --git a/source4/heimdal/lib/hx509/sel.c b/source4/heimdal/lib/hx509/sel.c index 5932ce84c3..561818c9f1 100644 --- a/source4/heimdal/lib/hx509/sel.c +++ b/source4/heimdal/lib/hx509/sel.c @@ -175,6 +175,7 @@ _hx509_expr_eval(hx509_context context, hx509_env env, struct hx_expr *expr) return eval_comp(context, env, expr->arg1); default: _hx509_abort("hx509 eval expr with unknown op: %d", (int)expr->op); + UNREACHABLE(return 0); } } -- cgit