Line data Source code
1 : /* crypto/asn1/a_verify.c */
2 : /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 : * All rights reserved.
4 : *
5 : * This package is an SSL implementation written
6 : * by Eric Young (eay@cryptsoft.com).
7 : * The implementation was written so as to conform with Netscapes SSL.
8 : *
9 : * This library is free for commercial and non-commercial use as long as
10 : * the following conditions are aheared to. The following conditions
11 : * apply to all code found in this distribution, be it the RC4, RSA,
12 : * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 : * included with this distribution is covered by the same copyright terms
14 : * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 : *
16 : * Copyright remains Eric Young's, and as such any Copyright notices in
17 : * the code are not to be removed.
18 : * If this package is used in a product, Eric Young should be given attribution
19 : * as the author of the parts of the library used.
20 : * This can be in the form of a textual message at program startup or
21 : * in documentation (online or textual) provided with the package.
22 : *
23 : * Redistribution and use in source and binary forms, with or without
24 : * modification, are permitted provided that the following conditions
25 : * are met:
26 : * 1. Redistributions of source code must retain the copyright
27 : * notice, this list of conditions and the following disclaimer.
28 : * 2. Redistributions in binary form must reproduce the above copyright
29 : * notice, this list of conditions and the following disclaimer in the
30 : * documentation and/or other materials provided with the distribution.
31 : * 3. All advertising materials mentioning features or use of this software
32 : * must display the following acknowledgement:
33 : * "This product includes cryptographic software written by
34 : * Eric Young (eay@cryptsoft.com)"
35 : * The word 'cryptographic' can be left out if the rouines from the library
36 : * being used are not cryptographic related :-).
37 : * 4. If you include any Windows specific code (or a derivative thereof) from
38 : * the apps directory (application code) you must include an acknowledgement:
39 : * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 : *
41 : * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 : * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 : * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 : * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 : * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 : * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 : * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 : * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 : * SUCH DAMAGE.
52 : *
53 : * The licence and distribution terms for any publically available version or
54 : * derivative of this code cannot be changed. i.e. this code cannot simply be
55 : * copied and put under another distribution licence
56 : * [including the GNU Public Licence.]
57 : */
58 :
59 : #include <stdio.h>
60 : #include <time.h>
61 :
62 : #include "cryptlib.h"
63 : #include "asn1_locl.h"
64 :
65 : #ifndef NO_SYS_TYPES_H
66 : # include <sys/types.h>
67 : #endif
68 :
69 : #include <openssl/bn.h>
70 : #include <openssl/x509.h>
71 : #include <openssl/objects.h>
72 : #include <openssl/buffer.h>
73 : #include <openssl/evp.h>
74 :
75 : #ifndef NO_ASN1_OLD
76 :
77 0 : int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *a, ASN1_BIT_STRING *signature,
78 : char *data, EVP_PKEY *pkey)
79 : {
80 : EVP_MD_CTX ctx;
81 : const EVP_MD *type;
82 : unsigned char *p, *buf_in = NULL;
83 : int ret = -1, i, inl;
84 :
85 0 : EVP_MD_CTX_init(&ctx);
86 0 : i = OBJ_obj2nid(a->algorithm);
87 0 : type = EVP_get_digestbyname(OBJ_nid2sn(i));
88 0 : if (type == NULL) {
89 0 : ASN1err(ASN1_F_ASN1_VERIFY, ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
90 0 : goto err;
91 : }
92 :
93 0 : if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7) {
94 0 : ASN1err(ASN1_F_ASN1_VERIFY, ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
95 0 : goto err;
96 : }
97 :
98 0 : inl = i2d(data, NULL);
99 0 : buf_in = OPENSSL_malloc((unsigned int)inl);
100 0 : if (buf_in == NULL) {
101 0 : ASN1err(ASN1_F_ASN1_VERIFY, ERR_R_MALLOC_FAILURE);
102 0 : goto err;
103 : }
104 0 : p = buf_in;
105 :
106 0 : i2d(data, &p);
107 0 : if (!EVP_VerifyInit_ex(&ctx, type, NULL)
108 0 : || !EVP_VerifyUpdate(&ctx, (unsigned char *)buf_in, inl)) {
109 0 : ASN1err(ASN1_F_ASN1_VERIFY, ERR_R_EVP_LIB);
110 : ret = 0;
111 0 : goto err;
112 : }
113 :
114 0 : OPENSSL_cleanse(buf_in, (unsigned int)inl);
115 0 : OPENSSL_free(buf_in);
116 :
117 0 : if (EVP_VerifyFinal(&ctx, (unsigned char *)signature->data,
118 0 : (unsigned int)signature->length, pkey) <= 0) {
119 0 : ASN1err(ASN1_F_ASN1_VERIFY, ERR_R_EVP_LIB);
120 : ret = 0;
121 0 : goto err;
122 : }
123 : /*
124 : * we don't need to zero the 'ctx' because we just checked public
125 : * information
126 : */
127 : /* memset(&ctx,0,sizeof(ctx)); */
128 : ret = 1;
129 : err:
130 0 : EVP_MD_CTX_cleanup(&ctx);
131 0 : return (ret);
132 : }
133 :
134 : #endif
135 :
136 370 : int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a,
137 : ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey)
138 : {
139 : EVP_MD_CTX ctx;
140 370 : unsigned char *buf_in = NULL;
141 : int ret = -1, inl;
142 :
143 : int mdnid, pknid;
144 :
145 370 : if (!pkey) {
146 0 : ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_PASSED_NULL_PARAMETER);
147 0 : return -1;
148 : }
149 :
150 370 : if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7) {
151 0 : ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
152 0 : return -1;
153 : }
154 :
155 370 : EVP_MD_CTX_init(&ctx);
156 :
157 : /* Convert signature OID into digest and public key OIDs */
158 370 : if (!OBJ_find_sigid_algs(OBJ_obj2nid(a->algorithm), &mdnid, &pknid)) {
159 0 : ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM);
160 0 : goto err;
161 : }
162 370 : if (mdnid == NID_undef) {
163 0 : if (!pkey->ameth || !pkey->ameth->item_verify) {
164 0 : ASN1err(ASN1_F_ASN1_ITEM_VERIFY,
165 : ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM);
166 0 : goto err;
167 : }
168 0 : ret = pkey->ameth->item_verify(&ctx, it, asn, a, signature, pkey);
169 : /*
170 : * Return value of 2 means carry on, anything else means we exit
171 : * straight away: either a fatal error of the underlying verification
172 : * routine handles all verification.
173 : */
174 0 : if (ret != 2)
175 : goto err;
176 : ret = -1;
177 : } else {
178 : const EVP_MD *type;
179 370 : type = EVP_get_digestbynid(mdnid);
180 370 : if (type == NULL) {
181 0 : ASN1err(ASN1_F_ASN1_ITEM_VERIFY,
182 : ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
183 0 : goto err;
184 : }
185 :
186 : /* Check public key OID matches public key type */
187 370 : if (EVP_PKEY_type(pknid) != pkey->ameth->pkey_id) {
188 0 : ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ASN1_R_WRONG_PUBLIC_KEY_TYPE);
189 0 : goto err;
190 : }
191 :
192 370 : if (!EVP_DigestVerifyInit(&ctx, NULL, type, NULL, pkey)) {
193 0 : ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_EVP_LIB);
194 : ret = 0;
195 0 : goto err;
196 : }
197 :
198 : }
199 :
200 370 : inl = ASN1_item_i2d(asn, &buf_in, it);
201 :
202 370 : if (buf_in == NULL) {
203 0 : ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_MALLOC_FAILURE);
204 0 : goto err;
205 : }
206 :
207 370 : if (!EVP_DigestVerifyUpdate(&ctx, buf_in, inl)) {
208 0 : ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_EVP_LIB);
209 : ret = 0;
210 0 : goto err;
211 : }
212 :
213 370 : OPENSSL_cleanse(buf_in, (unsigned int)inl);
214 370 : OPENSSL_free(buf_in);
215 :
216 370 : if (EVP_DigestVerifyFinal(&ctx, signature->data,
217 370 : (size_t)signature->length) <= 0) {
218 0 : ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_EVP_LIB);
219 : ret = 0;
220 0 : goto err;
221 : }
222 : /*
223 : * we don't need to zero the 'ctx' because we just checked public
224 : * information
225 : */
226 : /* memset(&ctx,0,sizeof(ctx)); */
227 : ret = 1;
228 : err:
229 370 : EVP_MD_CTX_cleanup(&ctx);
230 370 : return (ret);
231 : }
|