summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/x509/x509_cmp.c
diff options
context:
space:
mode:
authordjm <>2010-10-01 22:54:21 +0000
committerdjm <>2010-10-01 22:54:21 +0000
commit829fd51d4f8dde4a7f3bf54754f3c1d1a502f5e2 (patch)
treee03b9f1bd051e844b971936729e9df549a209130 /src/lib/libcrypto/x509/x509_cmp.c
parente6b755d2a53d3cac7a344dfdd6bf7c951cac754c (diff)
downloadopenbsd-829fd51d4f8dde4a7f3bf54754f3c1d1a502f5e2.tar.gz
openbsd-829fd51d4f8dde4a7f3bf54754f3c1d1a502f5e2.tar.bz2
openbsd-829fd51d4f8dde4a7f3bf54754f3c1d1a502f5e2.zip
import OpenSSL-1.0.0a
Diffstat (limited to 'src/lib/libcrypto/x509/x509_cmp.c')
-rw-r--r--src/lib/libcrypto/x509/x509_cmp.c237
1 files changed, 68 insertions, 169 deletions
diff --git a/src/lib/libcrypto/x509/x509_cmp.c b/src/lib/libcrypto/x509/x509_cmp.c
index 2faf92514a..4bc9da07e0 100644
--- a/src/lib/libcrypto/x509/x509_cmp.c
+++ b/src/lib/libcrypto/x509/x509_cmp.c
@@ -116,6 +116,13 @@ int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b)
116 return(X509_NAME_cmp(a->crl->issuer,b->crl->issuer)); 116 return(X509_NAME_cmp(a->crl->issuer,b->crl->issuer));
117 } 117 }
118 118
119#ifndef OPENSSL_NO_SHA
120int X509_CRL_match(const X509_CRL *a, const X509_CRL *b)
121 {
122 return memcmp(a->sha1_hash, b->sha1_hash, 20);
123 }
124#endif
125
119X509_NAME *X509_get_issuer_name(X509 *a) 126X509_NAME *X509_get_issuer_name(X509 *a)
120 { 127 {
121 return(a->cert_info->issuer); 128 return(a->cert_info->issuer);
@@ -126,6 +133,13 @@ unsigned long X509_issuer_name_hash(X509 *x)
126 return(X509_NAME_hash(x->cert_info->issuer)); 133 return(X509_NAME_hash(x->cert_info->issuer));
127 } 134 }
128 135
136#ifndef OPENSSL_NO_MD5
137unsigned long X509_issuer_name_hash_old(X509 *x)
138 {
139 return(X509_NAME_hash_old(x->cert_info->issuer));
140 }
141#endif
142
129X509_NAME *X509_get_subject_name(X509 *a) 143X509_NAME *X509_get_subject_name(X509 *a)
130 { 144 {
131 return(a->cert_info->subject); 145 return(a->cert_info->subject);
@@ -141,6 +155,13 @@ unsigned long X509_subject_name_hash(X509 *x)
141 return(X509_NAME_hash(x->cert_info->subject)); 155 return(X509_NAME_hash(x->cert_info->subject));
142 } 156 }
143 157
158#ifndef OPENSSL_NO_MD5
159unsigned long X509_subject_name_hash_old(X509 *x)
160 {
161 return(X509_NAME_hash_old(x->cert_info->subject));
162 }
163#endif
164
144#ifndef OPENSSL_NO_SHA 165#ifndef OPENSSL_NO_SHA
145/* Compare two certificates: they must be identical for 166/* Compare two certificates: they must be identical for
146 * this to work. NB: Although "cmp" operations are generally 167 * this to work. NB: Although "cmp" operations are generally
@@ -162,177 +183,63 @@ int X509_cmp(const X509 *a, const X509 *b)
162#endif 183#endif
163 184
164 185
165/* Case insensitive string comparision */ 186int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b)
166static int nocase_cmp(const ASN1_STRING *a, const ASN1_STRING *b)
167{
168 int i;
169
170 if (a->length != b->length)
171 return (a->length - b->length);
172
173 for (i=0; i<a->length; i++)
174 {
175 int ca, cb;
176
177 ca = tolower(a->data[i]);
178 cb = tolower(b->data[i]);
179
180 if (ca != cb)
181 return(ca-cb);
182 }
183 return 0;
184}
185
186/* Case insensitive string comparision with space normalization
187 * Space normalization - ignore leading, trailing spaces,
188 * multiple spaces between characters are replaced by single space
189 */
190static int nocase_spacenorm_cmp(const ASN1_STRING *a, const ASN1_STRING *b)
191{
192 unsigned char *pa = NULL, *pb = NULL;
193 int la, lb;
194
195 la = a->length;
196 lb = b->length;
197 pa = a->data;
198 pb = b->data;
199
200 /* skip leading spaces */
201 while (la > 0 && isspace(*pa))
202 {
203 la--;
204 pa++;
205 }
206 while (lb > 0 && isspace(*pb))
207 {
208 lb--;
209 pb++;
210 }
211
212 /* skip trailing spaces */
213 while (la > 0 && isspace(pa[la-1]))
214 la--;
215 while (lb > 0 && isspace(pb[lb-1]))
216 lb--;
217
218 /* compare strings with space normalization */
219 while (la > 0 && lb > 0)
220 { 187 {
221 int ca, cb; 188 int ret;
222
223 /* compare character */
224 ca = tolower(*pa);
225 cb = tolower(*pb);
226 if (ca != cb)
227 return (ca - cb);
228 189
229 pa++; pb++; 190 /* Ensure canonical encoding is present and up to date */
230 la--; lb--;
231 191
232 if (la <= 0 || lb <= 0) 192 if (!a->canon_enc || a->modified)
233 break; 193 {
194 ret = i2d_X509_NAME((X509_NAME *)a, NULL);
195 if (ret < 0)
196 return -2;
197 }
234 198
235 /* is white space next character ? */ 199 if (!b->canon_enc || b->modified)
236 if (isspace(*pa) && isspace(*pb))
237 { 200 {
238 /* skip remaining white spaces */ 201 ret = i2d_X509_NAME((X509_NAME *)b, NULL);
239 while (la > 0 && isspace(*pa)) 202 if (ret < 0)
240 { 203 return -2;
241 la--;
242 pa++;
243 }
244 while (lb > 0 && isspace(*pb))
245 {
246 lb--;
247 pb++;
248 }
249 } 204 }
250 }
251 if (la > 0 || lb > 0)
252 return la - lb;
253 205
254 return 0; 206 ret = a->canon_enclen - b->canon_enclen;
255}
256 207
257static int asn1_string_memcmp(ASN1_STRING *a, ASN1_STRING *b) 208 if (ret)
258 { 209 return ret;
259 int j;
260 j = a->length - b->length;
261 if (j)
262 return j;
263 return memcmp(a->data, b->data, a->length);
264 }
265 210
266#define STR_TYPE_CMP (B_ASN1_PRINTABLESTRING|B_ASN1_T61STRING|B_ASN1_UTF8STRING) 211 return memcmp(a->canon_enc, b->canon_enc, a->canon_enclen);
267 212
268int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b) 213 }
269 {
270 int i,j;
271 X509_NAME_ENTRY *na,*nb;
272 214
273 unsigned long nabit, nbbit; 215unsigned long X509_NAME_hash(X509_NAME *x)
216 {
217 unsigned long ret=0;
218 unsigned char md[SHA_DIGEST_LENGTH];
274 219
275 j = sk_X509_NAME_ENTRY_num(a->entries) 220 /* Make sure X509_NAME structure contains valid cached encoding */
276 - sk_X509_NAME_ENTRY_num(b->entries); 221 i2d_X509_NAME(x,NULL);
277 if (j) 222 EVP_Digest(x->canon_enc, x->canon_enclen, md, NULL, EVP_sha1(), NULL);
278 return j;
279 for (i=sk_X509_NAME_ENTRY_num(a->entries)-1; i>=0; i--)
280 {
281 na=sk_X509_NAME_ENTRY_value(a->entries,i);
282 nb=sk_X509_NAME_ENTRY_value(b->entries,i);
283 j=na->value->type-nb->value->type;
284 if (j)
285 {
286 nabit = ASN1_tag2bit(na->value->type);
287 nbbit = ASN1_tag2bit(nb->value->type);
288 if (!(nabit & STR_TYPE_CMP) ||
289 !(nbbit & STR_TYPE_CMP))
290 return j;
291 if (!asn1_string_memcmp(na->value, nb->value))
292 j = 0;
293 }
294 else if (na->value->type == V_ASN1_PRINTABLESTRING)
295 j=nocase_spacenorm_cmp(na->value, nb->value);
296 else if (na->value->type == V_ASN1_IA5STRING
297 && OBJ_obj2nid(na->object) == NID_pkcs9_emailAddress)
298 j=nocase_cmp(na->value, nb->value);
299 else
300 j = asn1_string_memcmp(na->value, nb->value);
301 if (j) return(j);
302 j=na->set-nb->set;
303 if (j) return(j);
304 }
305 223
306 /* We will check the object types after checking the values 224 ret=( ((unsigned long)md[0] )|((unsigned long)md[1]<<8L)|
307 * since the values will more often be different than the object 225 ((unsigned long)md[2]<<16L)|((unsigned long)md[3]<<24L)
308 * types. */ 226 )&0xffffffffL;
309 for (i=sk_X509_NAME_ENTRY_num(a->entries)-1; i>=0; i--) 227 return(ret);
310 {
311 na=sk_X509_NAME_ENTRY_value(a->entries,i);
312 nb=sk_X509_NAME_ENTRY_value(b->entries,i);
313 j=OBJ_cmp(na->object,nb->object);
314 if (j) return(j);
315 }
316 return(0);
317 } 228 }
318 229
230
319#ifndef OPENSSL_NO_MD5 231#ifndef OPENSSL_NO_MD5
320/* I now DER encode the name and hash it. Since I cache the DER encoding, 232/* I now DER encode the name and hash it. Since I cache the DER encoding,
321 * this is reasonably efficient. */ 233 * this is reasonably efficient. */
322unsigned long X509_NAME_hash(X509_NAME *x) 234
235unsigned long X509_NAME_hash_old(X509_NAME *x)
323 { 236 {
324 unsigned long ret=0; 237 unsigned long ret=0;
325 unsigned char md[16]; 238 unsigned char md[16];
326 EVP_MD_CTX md_ctx;
327 239
328 /* Make sure X509_NAME structure contains valid cached encoding */ 240 /* Make sure X509_NAME structure contains valid cached encoding */
329 i2d_X509_NAME(x,NULL); 241 i2d_X509_NAME(x,NULL);
330 EVP_MD_CTX_init(&md_ctx); 242 EVP_Digest(x->bytes->data, x->bytes->length, md, NULL, EVP_md5(), NULL);
331 EVP_MD_CTX_set_flags(&md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
332 EVP_DigestInit_ex(&md_ctx, EVP_md5(), NULL);
333 EVP_DigestUpdate(&md_ctx, x->bytes->data, x->bytes->length);
334 EVP_DigestFinal_ex(&md_ctx,md,NULL);
335 EVP_MD_CTX_cleanup(&md_ctx);
336 243
337 ret=( ((unsigned long)md[0] )|((unsigned long)md[1]<<8L)| 244 ret=( ((unsigned long)md[0] )|((unsigned long)md[1]<<8L)|
338 ((unsigned long)md[2]<<16L)|((unsigned long)md[3]<<24L) 245 ((unsigned long)md[2]<<16L)|((unsigned long)md[3]<<24L)
@@ -393,14 +300,19 @@ ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x)
393 300
394int X509_check_private_key(X509 *x, EVP_PKEY *k) 301int X509_check_private_key(X509 *x, EVP_PKEY *k)
395 { 302 {
396 EVP_PKEY *xk=NULL; 303 EVP_PKEY *xk;
397 int ok=0; 304 int ret;
398 305
399 xk=X509_get_pubkey(x); 306 xk=X509_get_pubkey(x);
400 switch (EVP_PKEY_cmp(xk, k)) 307
308 if (xk)
309 ret = EVP_PKEY_cmp(xk, k);
310 else
311 ret = -2;
312
313 switch (ret)
401 { 314 {
402 case 1: 315 case 1:
403 ok=1;
404 break; 316 break;
405 case 0: 317 case 0:
406 X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_KEY_VALUES_MISMATCH); 318 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)
409 X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_KEY_TYPE_MISMATCH); 321 X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_KEY_TYPE_MISMATCH);
410 break; 322 break;
411 case -2: 323 case -2:
412#ifndef OPENSSL_NO_EC
413 if (k->type == EVP_PKEY_EC)
414 {
415 X509err(X509_F_X509_CHECK_PRIVATE_KEY, ERR_R_EC_LIB);
416 break;
417 }
418#endif
419#ifndef OPENSSL_NO_DH
420 if (k->type == EVP_PKEY_DH)
421 {
422 /* No idea */
423 X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_CANT_CHECK_DH_KEY);
424 break;
425 }
426#endif
427 X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_UNKNOWN_KEY_TYPE); 324 X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_UNKNOWN_KEY_TYPE);
428 } 325 }
429 326 if (xk)
430 EVP_PKEY_free(xk); 327 EVP_PKEY_free(xk);
431 return(ok); 328 if (ret > 0)
329 return 1;
330 return 0;
432 } 331 }