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);
#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]);
-
- if (ca != cb)
- return(ca-cb);
- }
- return 0;
-}
+ /* Ensure canonical encoding is present and up to date */
-/* 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--;
+ if (!a->canon_enc || a->modified)
+ {
+ ret = i2d_X509_NAME((X509_NAME *)a, NULL);
+ if (ret < 0)
+ return -2;
+ }
- /* compare strings with space normalization */
- while (la > 0 && lb > 0)
- {
- int ca, cb;
+ if (!b->canon_enc || b->modified)
+ {
+ ret = i2d_X509_NAME((X509_NAME *)b, NULL);
+ if (ret < 0)
+ return -2;
+ }
- /* compare character */
- ca = tolower(*pa);
- cb = tolower(*pb);
- if (ca != cb)
- return (ca - cb);
+ ret = a->canon_enclen - b->canon_enclen;
- pa++; pb++;
- la--; lb--;
+ if (ret)
+ return ret;
- if (la <= 0 || lb <= 0)
- break;
+ return memcmp(a->canon_enc, b->canon_enc, a->canon_enclen);
- /* 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;
-}
-
-int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b)
+unsigned long X509_NAME_hash(X509_NAME *x)
{
- int i,j;
- X509_NAME_ENTRY *na,*nb;
-
- if (sk_X509_NAME_ENTRY_num(a->entries)
- != sk_X509_NAME_ENTRY_num(b->entries))
- return sk_X509_NAME_ENTRY_num(a->entries)
- -sk_X509_NAME_ENTRY_num(b->entries);
- 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) return(j);
- 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=na->value->length-nb->value->length;
- if (j) return(j);
- j=memcmp(na->value->data,nb->value->data,
- na->value->length);
- }
- if (j) return(j);
- j=na->set-nb->set;
- if (j) return(j);
- }
+ unsigned long ret=0;
+ unsigned char md[SHA_DIGEST_LENGTH];
- /* 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);
+ /* 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);
+
+ 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];
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);
- if (xk->type != k->type)
- {
- X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_KEY_TYPE_MISMATCH);
- goto err;
- }
- switch (k->type)
+
+ if (xk)
+ ret = EVP_PKEY_cmp(xk, k);
+ else
+ ret = -2;
+
+ switch (ret)
{
-#ifndef OPENSSL_NO_RSA
- case EVP_PKEY_RSA:
- if (BN_cmp(xk->pkey.rsa->n,k->pkey.rsa->n) != 0
- || BN_cmp(xk->pkey.rsa->e,k->pkey.rsa->e) != 0)
- {
- X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_KEY_VALUES_MISMATCH);
- goto err;
- }
+ case 1:
break;
-#endif
-#ifndef OPENSSL_NO_DSA
- case EVP_PKEY_DSA:
- if (BN_cmp(xk->pkey.dsa->pub_key,k->pkey.dsa->pub_key) != 0)
- {
- X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_KEY_VALUES_MISMATCH);
- goto err;
- }
+ case 0:
+ X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_KEY_VALUES_MISMATCH);
break;
-#endif
-#ifndef OPENSSL_NO_EC
- case EVP_PKEY_EC:
- {
- int r = EC_POINT_cmp(xk->pkey.eckey->group,
- xk->pkey.eckey->pub_key,k->pkey.eckey->pub_key,NULL);
- if (r != 0)
- {
- if (r == 1)
- X509err(X509_F_X509_CHECK_PRIVATE_KEY, X509_R_KEY_VALUES_MISMATCH);
- else
- X509err(X509_F_X509_CHECK_PRIVATE_KEY, ERR_R_EC_LIB);
-
- goto err;
- }
- }
- break;
-#endif
-#ifndef OPENSSL_NO_DH
- case EVP_PKEY_DH:
- /* No idea */
- X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_CANT_CHECK_DH_KEY);
- goto err;
-#endif
- default:
+ case -1:
+ X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_KEY_TYPE_MISMATCH);
+ break;
+ case -2:
X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_UNKNOWN_KEY_TYPE);
- goto err;
}
-
- ok=1;
-err:
- EVP_PKEY_free(xk);
- return(ok);
+ if (xk)
+ EVP_PKEY_free(xk);
+ if (ret > 0)
+ return 1;
+ return 0;
}