| Index: openssl/crypto/x509/x509_cmp.c
|
| ===================================================================
|
| --- openssl/crypto/x509/x509_cmp.c (revision 105093)
|
| +++ openssl/crypto/x509/x509_cmp.c (working copy)
|
| @@ -116,6 +116,13 @@
|
| return(X509_NAME_cmp(a->crl->issuer,b->crl->issuer));
|
| }
|
|
|
| +#ifndef OPENSSL_NO_SHA
|
| +int X509_CRL_match(const X509_CRL *a, const X509_CRL *b)
|
| + {
|
| + return memcmp(a->sha1_hash, b->sha1_hash, 20);
|
| + }
|
| +#endif
|
| +
|
| X509_NAME *X509_get_issuer_name(X509 *a)
|
| {
|
| return(a->cert_info->issuer);
|
| @@ -126,6 +133,13 @@
|
| return(X509_NAME_hash(x->cert_info->issuer));
|
| }
|
|
|
| +#ifndef OPENSSL_NO_MD5
|
| +unsigned long X509_issuer_name_hash_old(X509 *x)
|
| + {
|
| + return(X509_NAME_hash_old(x->cert_info->issuer));
|
| + }
|
| +#endif
|
| +
|
| X509_NAME *X509_get_subject_name(X509 *a)
|
| {
|
| return(a->cert_info->subject);
|
| @@ -141,6 +155,13 @@
|
| return(X509_NAME_hash(x->cert_info->subject));
|
| }
|
|
|
| +#ifndef OPENSSL_NO_MD5
|
| +unsigned long X509_subject_name_hash_old(X509 *x)
|
| + {
|
| + return(X509_NAME_hash_old(x->cert_info->subject));
|
| + }
|
| +#endif
|
| +
|
| #ifndef OPENSSL_NO_SHA
|
| /* Compare two certificates: they must be identical for
|
| * this to work. NB: Although "cmp" operations are generally
|
| @@ -162,177 +183,63 @@
|
| #endif
|
|
|
|
|
| -/* Case insensitive string comparision */
|
| -static int nocase_cmp(const ASN1_STRING *a, const ASN1_STRING *b)
|
| -{
|
| - int i;
|
| -
|
| - if (a->length != b->length)
|
| - return (a->length - b->length);
|
| -
|
| - for (i=0; i<a->length; i++)
|
| +int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b)
|
| {
|
| - int ca, cb;
|
| + int ret;
|
|
|
| - ca = tolower(a->data[i]);
|
| - cb = tolower(b->data[i]);
|
| + /* Ensure canonical encoding is present and up to date */
|
|
|
| - if (ca != cb)
|
| - return(ca-cb);
|
| - }
|
| - return 0;
|
| -}
|
| + if (!a->canon_enc || a->modified)
|
| + {
|
| + ret = i2d_X509_NAME((X509_NAME *)a, NULL);
|
| + if (ret < 0)
|
| + return -2;
|
| + }
|
|
|
| -/* Case insensitive string comparision with space normalization
|
| - * Space normalization - ignore leading, trailing spaces,
|
| - * multiple spaces between characters are replaced by single space
|
| - */
|
| -static int nocase_spacenorm_cmp(const ASN1_STRING *a, const ASN1_STRING *b)
|
| -{
|
| - unsigned char *pa = NULL, *pb = NULL;
|
| - int la, lb;
|
| -
|
| - la = a->length;
|
| - lb = b->length;
|
| - pa = a->data;
|
| - pb = b->data;
|
| + if (!b->canon_enc || b->modified)
|
| + {
|
| + ret = i2d_X509_NAME((X509_NAME *)b, NULL);
|
| + if (ret < 0)
|
| + return -2;
|
| + }
|
|
|
| - /* skip leading spaces */
|
| - while (la > 0 && isspace(*pa))
|
| - {
|
| - la--;
|
| - pa++;
|
| - }
|
| - while (lb > 0 && isspace(*pb))
|
| - {
|
| - lb--;
|
| - pb++;
|
| - }
|
| + ret = a->canon_enclen - b->canon_enclen;
|
|
|
| - /* skip trailing spaces */
|
| - while (la > 0 && isspace(pa[la-1]))
|
| - la--;
|
| - while (lb > 0 && isspace(pb[lb-1]))
|
| - lb--;
|
| + if (ret)
|
| + return ret;
|
|
|
| - /* compare strings with space normalization */
|
| - while (la > 0 && lb > 0)
|
| - {
|
| - int ca, cb;
|
| + return memcmp(a->canon_enc, b->canon_enc, a->canon_enclen);
|
|
|
| - /* compare character */
|
| - ca = tolower(*pa);
|
| - cb = tolower(*pb);
|
| - if (ca != cb)
|
| - return (ca - cb);
|
| -
|
| - pa++; pb++;
|
| - la--; lb--;
|
| -
|
| - if (la <= 0 || lb <= 0)
|
| - break;
|
| -
|
| - /* is white space next character ? */
|
| - if (isspace(*pa) && isspace(*pb))
|
| - {
|
| - /* skip remaining white spaces */
|
| - while (la > 0 && isspace(*pa))
|
| - {
|
| - la--;
|
| - pa++;
|
| - }
|
| - while (lb > 0 && isspace(*pb))
|
| - {
|
| - lb--;
|
| - pb++;
|
| - }
|
| - }
|
| }
|
| - if (la > 0 || lb > 0)
|
| - return la - lb;
|
|
|
| - return 0;
|
| -}
|
| -
|
| -static int asn1_string_memcmp(ASN1_STRING *a, ASN1_STRING *b)
|
| +unsigned long X509_NAME_hash(X509_NAME *x)
|
| {
|
| - int j;
|
| - j = a->length - b->length;
|
| - if (j)
|
| - return j;
|
| - return memcmp(a->data, b->data, a->length);
|
| - }
|
| + unsigned long ret=0;
|
| + unsigned char md[SHA_DIGEST_LENGTH];
|
|
|
| -#define STR_TYPE_CMP (B_ASN1_PRINTABLESTRING|B_ASN1_T61STRING|B_ASN1_UTF8STRING)
|
| + /* Make sure X509_NAME structure contains valid cached encoding */
|
| + i2d_X509_NAME(x,NULL);
|
| + EVP_Digest(x->canon_enc, x->canon_enclen, md, NULL, EVP_sha1(), NULL);
|
|
|
| -int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b)
|
| - {
|
| - int i,j;
|
| - X509_NAME_ENTRY *na,*nb;
|
| -
|
| - unsigned long nabit, nbbit;
|
| -
|
| - j = sk_X509_NAME_ENTRY_num(a->entries)
|
| - - sk_X509_NAME_ENTRY_num(b->entries);
|
| - if (j)
|
| - return j;
|
| - for (i=sk_X509_NAME_ENTRY_num(a->entries)-1; i>=0; i--)
|
| - {
|
| - na=sk_X509_NAME_ENTRY_value(a->entries,i);
|
| - nb=sk_X509_NAME_ENTRY_value(b->entries,i);
|
| - j=na->value->type-nb->value->type;
|
| - if (j)
|
| - {
|
| - nabit = ASN1_tag2bit(na->value->type);
|
| - nbbit = ASN1_tag2bit(nb->value->type);
|
| - if (!(nabit & STR_TYPE_CMP) ||
|
| - !(nbbit & STR_TYPE_CMP))
|
| - return j;
|
| - if (!asn1_string_memcmp(na->value, nb->value))
|
| - j = 0;
|
| - }
|
| - else if (na->value->type == V_ASN1_PRINTABLESTRING)
|
| - j=nocase_spacenorm_cmp(na->value, nb->value);
|
| - else if (na->value->type == V_ASN1_IA5STRING
|
| - && OBJ_obj2nid(na->object) == NID_pkcs9_emailAddress)
|
| - j=nocase_cmp(na->value, nb->value);
|
| - else
|
| - j = asn1_string_memcmp(na->value, nb->value);
|
| - if (j) return(j);
|
| - j=na->set-nb->set;
|
| - if (j) return(j);
|
| - }
|
| -
|
| - /* We will check the object types after checking the values
|
| - * since the values will more often be different than the object
|
| - * types. */
|
| - for (i=sk_X509_NAME_ENTRY_num(a->entries)-1; i>=0; i--)
|
| - {
|
| - na=sk_X509_NAME_ENTRY_value(a->entries,i);
|
| - nb=sk_X509_NAME_ENTRY_value(b->entries,i);
|
| - j=OBJ_cmp(na->object,nb->object);
|
| - if (j) return(j);
|
| - }
|
| - return(0);
|
| + ret=( ((unsigned long)md[0] )|((unsigned long)md[1]<<8L)|
|
| + ((unsigned long)md[2]<<16L)|((unsigned long)md[3]<<24L)
|
| + )&0xffffffffL;
|
| + return(ret);
|
| }
|
|
|
| +
|
| #ifndef OPENSSL_NO_MD5
|
| /* I now DER encode the name and hash it. Since I cache the DER encoding,
|
| * this is reasonably efficient. */
|
| -unsigned long X509_NAME_hash(X509_NAME *x)
|
| +
|
| +unsigned long X509_NAME_hash_old(X509_NAME *x)
|
| {
|
| unsigned long ret=0;
|
| unsigned char md[16];
|
| - EVP_MD_CTX md_ctx;
|
|
|
| /* Make sure X509_NAME structure contains valid cached encoding */
|
| i2d_X509_NAME(x,NULL);
|
| - EVP_MD_CTX_init(&md_ctx);
|
| - EVP_MD_CTX_set_flags(&md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
|
| - EVP_DigestInit_ex(&md_ctx, EVP_md5(), NULL);
|
| - EVP_DigestUpdate(&md_ctx, x->bytes->data, x->bytes->length);
|
| - EVP_DigestFinal_ex(&md_ctx,md,NULL);
|
| - EVP_MD_CTX_cleanup(&md_ctx);
|
| + EVP_Digest(x->bytes->data, x->bytes->length, md, NULL, EVP_md5(), NULL);
|
|
|
| ret=( ((unsigned long)md[0] )|((unsigned long)md[1]<<8L)|
|
| ((unsigned long)md[2]<<16L)|((unsigned long)md[3]<<24L)
|
| @@ -393,14 +300,19 @@
|
|
|
| int X509_check_private_key(X509 *x, EVP_PKEY *k)
|
| {
|
| - EVP_PKEY *xk=NULL;
|
| - int ok=0;
|
| + EVP_PKEY *xk;
|
| + int ret;
|
|
|
| xk=X509_get_pubkey(x);
|
| - switch (EVP_PKEY_cmp(xk, k))
|
| +
|
| + if (xk)
|
| + ret = EVP_PKEY_cmp(xk, k);
|
| + else
|
| + ret = -2;
|
| +
|
| + switch (ret)
|
| {
|
| case 1:
|
| - ok=1;
|
| break;
|
| case 0:
|
| X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_KEY_VALUES_MISMATCH);
|
| @@ -409,24 +321,11 @@
|
| X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_KEY_TYPE_MISMATCH);
|
| break;
|
| case -2:
|
| -#ifndef OPENSSL_NO_EC
|
| - if (k->type == EVP_PKEY_EC)
|
| - {
|
| - X509err(X509_F_X509_CHECK_PRIVATE_KEY, ERR_R_EC_LIB);
|
| - break;
|
| - }
|
| -#endif
|
| -#ifndef OPENSSL_NO_DH
|
| - if (k->type == EVP_PKEY_DH)
|
| - {
|
| - /* No idea */
|
| - X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_CANT_CHECK_DH_KEY);
|
| - break;
|
| - }
|
| -#endif
|
| X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_UNKNOWN_KEY_TYPE);
|
| }
|
| -
|
| - EVP_PKEY_free(xk);
|
| - return(ok);
|
| + if (xk)
|
| + EVP_PKEY_free(xk);
|
| + if (ret > 0)
|
| + return 1;
|
| + return 0;
|
| }
|
|
|