aboutsummaryrefslogtreecommitdiff
path: root/openssl/crypto/x509/x509_cmp.c
diff options
context:
space:
mode:
Diffstat (limited to 'openssl/crypto/x509/x509_cmp.c')
-rw-r--r--openssl/crypto/x509/x509_cmp.c237
1 files changed, 68 insertions, 169 deletions
diff --git a/openssl/crypto/x509/x509_cmp.c b/openssl/crypto/x509/x509_cmp.c
index 2faf92514..4bc9da07e 100644
--- a/openssl/crypto/x509/x509_cmp.c
+++ b/openssl/crypto/x509/x509_cmp.c
@@ -116,6 +116,13 @@ int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b)
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 @@ unsigned long X509_issuer_name_hash(X509 *x)
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 @@ unsigned long X509_subject_name_hash(X509 *x)
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 @@ int X509_cmp(const X509 *a, const X509 *b)
#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 ca, cb;
-
- ca = tolower(a->data[i]);
- cb = tolower(b->data[i]);
-
- if (ca != cb)
- return(ca-cb);
- }
- return 0;
-}
-
-/* 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;
-
- /* skip leading spaces */
- while (la > 0 && isspace(*pa))
- {
- la--;
- pa++;
- }
- while (lb > 0 && isspace(*pb))
- {
- lb--;
- pb++;
- }
-
- /* skip trailing spaces */
- while (la > 0 && isspace(pa[la-1]))
- la--;
- while (lb > 0 && isspace(pb[lb-1]))
- lb--;
-
- /* compare strings with space normalization */
- while (la > 0 && lb > 0)
+int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b)
{
- int ca, cb;
-
- /* compare character */
- ca = tolower(*pa);
- cb = tolower(*pb);
- if (ca != cb)
- return (ca - cb);
+ int ret;
- pa++; pb++;
- la--; lb--;
+ /* Ensure canonical encoding is present and up to date */
- if (la <= 0 || lb <= 0)
- break;
+ if (!a->canon_enc || a->modified)
+ {
+ ret = i2d_X509_NAME((X509_NAME *)a, NULL);
+ if (ret < 0)
+ return -2;
+ }
- /* is white space next character ? */
- if (isspace(*pa) && isspace(*pb))
+ if (!b->canon_enc || b->modified)
{
- /* skip remaining white spaces */
- while (la > 0 && isspace(*pa))
- {
- la--;
- pa++;
- }
- while (lb > 0 && isspace(*pb))
- {
- lb--;
- pb++;
- }
+ ret = i2d_X509_NAME((X509_NAME *)b, NULL);
+ if (ret < 0)
+ return -2;
}
- }
- if (la > 0 || lb > 0)
- return la - lb;
- return 0;
-}
+ ret = a->canon_enclen - b->canon_enclen;
-static int asn1_string_memcmp(ASN1_STRING *a, ASN1_STRING *b)
- {
- int j;
- j = a->length - b->length;
- if (j)
- return j;
- return memcmp(a->data, b->data, a->length);
- }
+ if (ret)
+ return ret;
-#define STR_TYPE_CMP (B_ASN1_PRINTABLESTRING|B_ASN1_T61STRING|B_ASN1_UTF8STRING)
+ return memcmp(a->canon_enc, b->canon_enc, a->canon_enclen);
-int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b)
- {
- int i,j;
- X509_NAME_ENTRY *na,*nb;
+ }
- unsigned long nabit, nbbit;
+unsigned long X509_NAME_hash(X509_NAME *x)
+ {
+ unsigned long ret=0;
+ unsigned char md[SHA_DIGEST_LENGTH];
- 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);
- }
+ /* 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);
- /* 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 @@ ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x)
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 @@ int X509_check_private_key(X509 *x, EVP_PKEY *k)
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;
}