summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/ts/ts_rsp_verify.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/lib/libcrypto/ts/ts_rsp_verify.c507
1 files changed, 256 insertions, 251 deletions
diff --git a/src/lib/libcrypto/ts/ts_rsp_verify.c b/src/lib/libcrypto/ts/ts_rsp_verify.c
index 7484b10d60..66e35dab3a 100644
--- a/src/lib/libcrypto/ts/ts_rsp_verify.c
+++ b/src/lib/libcrypto/ts/ts_rsp_verify.c
@@ -10,7 +10,7 @@
10 * are met: 10 * are met:
11 * 11 *
12 * 1. Redistributions of source code must retain the above copyright 12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer. 13 * notice, this list of conditions and the following disclaimer.
14 * 14 *
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in 16 * notice, this list of conditions and the following disclaimer in
@@ -65,38 +65,39 @@
65/* Private function declarations. */ 65/* Private function declarations. */
66 66
67static int TS_verify_cert(X509_STORE *store, STACK_OF(X509) *untrusted, 67static int TS_verify_cert(X509_STORE *store, STACK_OF(X509) *untrusted,
68 X509 *signer, STACK_OF(X509) **chain); 68 X509 *signer, STACK_OF(X509) **chain);
69static int TS_check_signing_certs(PKCS7_SIGNER_INFO *si, STACK_OF(X509) *chain); 69static int TS_check_signing_certs(PKCS7_SIGNER_INFO *si, STACK_OF(X509) *chain);
70static ESS_SIGNING_CERT *ESS_get_signing_cert(PKCS7_SIGNER_INFO *si); 70static ESS_SIGNING_CERT *ESS_get_signing_cert(PKCS7_SIGNER_INFO *si);
71static int TS_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert); 71static int TS_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert);
72static int TS_issuer_serial_cmp(ESS_ISSUER_SERIAL *is, X509_CINF *cinfo); 72static int TS_issuer_serial_cmp(ESS_ISSUER_SERIAL *is, X509_CINF *cinfo);
73static int int_TS_RESP_verify_token(TS_VERIFY_CTX *ctx, 73static int int_TS_RESP_verify_token(TS_VERIFY_CTX *ctx,
74 PKCS7 *token, TS_TST_INFO *tst_info); 74 PKCS7 *token, TS_TST_INFO *tst_info);
75static int TS_check_status_info(TS_RESP *response); 75static int TS_check_status_info(TS_RESP *response);
76static char *TS_get_status_text(STACK_OF(ASN1_UTF8STRING) *text); 76static char *TS_get_status_text(STACK_OF(ASN1_UTF8STRING) *text);
77static int TS_check_policy(ASN1_OBJECT *req_oid, TS_TST_INFO *tst_info); 77static int TS_check_policy(ASN1_OBJECT *req_oid, TS_TST_INFO *tst_info);
78static int TS_compute_imprint(BIO *data, TS_TST_INFO *tst_info, 78static int TS_compute_imprint(BIO *data, TS_TST_INFO *tst_info,
79 X509_ALGOR **md_alg, 79 X509_ALGOR **md_alg,
80 unsigned char **imprint, unsigned *imprint_len); 80 unsigned char **imprint, unsigned *imprint_len);
81static int TS_check_imprints(X509_ALGOR *algor_a, 81static int TS_check_imprints(X509_ALGOR *algor_a,
82 unsigned char *imprint_a, unsigned len_a, 82 unsigned char *imprint_a, unsigned len_a,
83 TS_TST_INFO *tst_info); 83 TS_TST_INFO *tst_info);
84static int TS_check_nonces(const ASN1_INTEGER *a, TS_TST_INFO *tst_info); 84static int TS_check_nonces(const ASN1_INTEGER *a, TS_TST_INFO *tst_info);
85static int TS_check_signer_name(GENERAL_NAME *tsa_name, X509 *signer); 85static int TS_check_signer_name(GENERAL_NAME *tsa_name, X509 *signer);
86static int TS_find_name(STACK_OF(GENERAL_NAME) *gen_names, GENERAL_NAME *name); 86static int TS_find_name(STACK_OF(GENERAL_NAME) *gen_names, GENERAL_NAME *name);
87 87
88/* 88/*
89 * Local mapping between response codes and descriptions. 89 * Local mapping between response codes and descriptions.
90 * Don't forget to change TS_STATUS_BUF_SIZE when modifying 90 * Don't forget to change TS_STATUS_BUF_SIZE when modifying
91 * the elements of this array. 91 * the elements of this array.
92 */ 92 */
93static const char *TS_status_text[] = 93static const char *TS_status_text[] = {
94 { "granted", 94 "granted",
95 "grantedWithMods", 95 "grantedWithMods",
96 "rejection", 96 "rejection",
97 "waiting", 97 "waiting",
98 "revocationWarning", 98 "revocationWarning",
99 "revocationNotification" }; 99 "revocationNotification"
100};
100 101
101#define TS_STATUS_TEXT_SIZE (sizeof(TS_status_text)/sizeof(*TS_status_text)) 102#define TS_STATUS_TEXT_SIZE (sizeof(TS_status_text)/sizeof(*TS_status_text))
102 103
@@ -106,19 +107,19 @@ static const char *TS_status_text[] =
106 */ 107 */
107#define TS_STATUS_BUF_SIZE 256 108#define TS_STATUS_BUF_SIZE 256
108 109
109static struct 110static struct {
110 {
111 int code; 111 int code;
112 const char *text; 112 const char *text;
113 } TS_failure_info[] = 113} TS_failure_info[] = {
114 { { TS_INFO_BAD_ALG, "badAlg" }, 114 { TS_INFO_BAD_ALG, "badAlg" },
115 { TS_INFO_BAD_REQUEST, "badRequest" }, 115 { TS_INFO_BAD_REQUEST, "badRequest" },
116 { TS_INFO_BAD_DATA_FORMAT, "badDataFormat" }, 116 { TS_INFO_BAD_DATA_FORMAT, "badDataFormat" },
117 { TS_INFO_TIME_NOT_AVAILABLE, "timeNotAvailable" }, 117 { TS_INFO_TIME_NOT_AVAILABLE, "timeNotAvailable" },
118 { TS_INFO_UNACCEPTED_POLICY, "unacceptedPolicy" }, 118 { TS_INFO_UNACCEPTED_POLICY, "unacceptedPolicy" },
119 { TS_INFO_UNACCEPTED_EXTENSION, "unacceptedExtension" }, 119 { TS_INFO_UNACCEPTED_EXTENSION, "unacceptedExtension" },
120 { TS_INFO_ADD_INFO_NOT_AVAILABLE, "addInfoNotAvailable" }, 120 { TS_INFO_ADD_INFO_NOT_AVAILABLE, "addInfoNotAvailable" },
121 { TS_INFO_SYSTEM_FAILURE, "systemFailure" } }; 121 { TS_INFO_SYSTEM_FAILURE, "systemFailure" }
122};
122 123
123#define TS_FAILURE_INFO_SIZE (sizeof(TS_failure_info) / \ 124#define TS_FAILURE_INFO_SIZE (sizeof(TS_failure_info) / \
124 sizeof(*TS_failure_info)) 125 sizeof(*TS_failure_info))
@@ -137,9 +138,10 @@ static struct
137 * - Verify the signature value. 138 * - Verify the signature value.
138 * - Returns the signer certificate in 'signer', if 'signer' is not NULL. 139 * - Returns the signer certificate in 'signer', if 'signer' is not NULL.
139 */ 140 */
140int TS_RESP_verify_signature(PKCS7 *token, STACK_OF(X509) *certs, 141int
141 X509_STORE *store, X509 **signer_out) 142TS_RESP_verify_signature(PKCS7 *token, STACK_OF(X509) *certs,
142 { 143 X509_STORE *store, X509 **signer_out)
144{
143 STACK_OF(PKCS7_SIGNER_INFO) *sinfos = NULL; 145 STACK_OF(PKCS7_SIGNER_INFO) *sinfos = NULL;
144 PKCS7_SIGNER_INFO *si; 146 PKCS7_SIGNER_INFO *si;
145 STACK_OF(X509) *signers = NULL; 147 STACK_OF(X509) *signers = NULL;
@@ -150,87 +152,86 @@ int TS_RESP_verify_signature(PKCS7 *token, STACK_OF(X509) *certs,
150 BIO *p7bio = NULL; 152 BIO *p7bio = NULL;
151 153
152 /* Some sanity checks first. */ 154 /* Some sanity checks first. */
153 if (!token) 155 if (!token) {
154 {
155 TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_INVALID_NULL_POINTER); 156 TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_INVALID_NULL_POINTER);
156 goto err; 157 goto err;
157 } 158 }
158 159
159 /* Check for the correct content type */ 160 /* Check for the correct content type */
160 if(!PKCS7_type_is_signed(token)) 161 if (!PKCS7_type_is_signed(token)) {
161 {
162 TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_WRONG_CONTENT_TYPE); 162 TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_WRONG_CONTENT_TYPE);
163 goto err; 163 goto err;
164 } 164 }
165 165
166 /* Check if there is one and only one signer. */ 166 /* Check if there is one and only one signer. */
167 sinfos = PKCS7_get_signer_info(token); 167 sinfos = PKCS7_get_signer_info(token);
168 if (!sinfos || sk_PKCS7_SIGNER_INFO_num(sinfos) != 1) 168 if (!sinfos || sk_PKCS7_SIGNER_INFO_num(sinfos) != 1) {
169 {
170 TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, 169 TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE,
171 TS_R_THERE_MUST_BE_ONE_SIGNER); 170 TS_R_THERE_MUST_BE_ONE_SIGNER);
172 goto err; 171 goto err;
173 } 172 }
174 si = sk_PKCS7_SIGNER_INFO_value(sinfos, 0); 173 si = sk_PKCS7_SIGNER_INFO_value(sinfos, 0);
175 174
176 /* Check for no content: no data to verify signature. */ 175 /* Check for no content: no data to verify signature. */
177 if (PKCS7_get_detached(token)) 176 if (PKCS7_get_detached(token)) {
178 {
179 TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_NO_CONTENT); 177 TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_NO_CONTENT);
180 goto err; 178 goto err;
181 } 179 }
182 180
183 /* Get hold of the signer certificate, search only internal 181 /* Get hold of the signer certificate, search only internal
184 certificates if it was requested. */ 182 certificates if it was requested. */
185 signers = PKCS7_get0_signers(token, certs, 0); 183 signers = PKCS7_get0_signers(token, certs, 0);
186 if (!signers || sk_X509_num(signers) != 1) goto err; 184 if (!signers || sk_X509_num(signers) != 1)
185 goto err;
187 signer = sk_X509_value(signers, 0); 186 signer = sk_X509_value(signers, 0);
188 187
189 /* Now verify the certificate. */ 188 /* Now verify the certificate. */
190 if (!TS_verify_cert(store, certs, signer, &chain)) goto err; 189 if (!TS_verify_cert(store, certs, signer, &chain))
190 goto err;
191 191
192 /* Check if the signer certificate is consistent with the 192 /* Check if the signer certificate is consistent with the
193 ESS extension. */ 193 ESS extension. */
194 if (!TS_check_signing_certs(si, chain)) goto err; 194 if (!TS_check_signing_certs(si, chain))
195 goto err;
195 196
196 /* Creating the message digest. */ 197 /* Creating the message digest. */
197 p7bio = PKCS7_dataInit(token, NULL); 198 p7bio = PKCS7_dataInit(token, NULL);
198 199
199 /* We now have to 'read' from p7bio to calculate digests etc. */ 200 /* We now have to 'read' from p7bio to calculate digests etc. */
200 while ((i = BIO_read(p7bio,buf,sizeof(buf))) > 0); 201 while ((i = BIO_read(p7bio, buf, sizeof(buf))) > 0)
202 ;
201 203
202 /* Verifying the signature. */ 204 /* Verifying the signature. */
203 j = PKCS7_signatureVerify(p7bio, token, si, signer); 205 j = PKCS7_signatureVerify(p7bio, token, si, signer);
204 if (j <= 0) 206 if (j <= 0) {
205 {
206 TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_SIGNATURE_FAILURE); 207 TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_SIGNATURE_FAILURE);
207 goto err; 208 goto err;
208 } 209 }
209 210
210 /* Return the signer certificate if needed. */ 211 /* Return the signer certificate if needed. */
211 if (signer_out) 212 if (signer_out) {
212 {
213 *signer_out = signer; 213 *signer_out = signer;
214 CRYPTO_add(&signer->references, 1, CRYPTO_LOCK_X509); 214 CRYPTO_add(&signer->references, 1, CRYPTO_LOCK_X509);
215 } 215 }
216 216
217 ret = 1; 217 ret = 1;
218 218
219 err: 219err:
220 BIO_free_all(p7bio); 220 BIO_free_all(p7bio);
221 sk_X509_pop_free(chain, X509_free); 221 sk_X509_pop_free(chain, X509_free);
222 sk_X509_free(signers); 222 sk_X509_free(signers);
223 223
224 return ret; 224 return ret;
225 } 225}
226 226
227/* 227/*
228 * The certificate chain is returned in chain. Caller is responsible for 228 * The certificate chain is returned in chain. Caller is responsible for
229 * freeing the vector. 229 * freeing the vector.
230 */ 230 */
231static int TS_verify_cert(X509_STORE *store, STACK_OF(X509) *untrusted, 231static int
232 X509 *signer, STACK_OF(X509) **chain) 232TS_verify_cert(X509_STORE *store, STACK_OF(X509) *untrusted, X509 *signer,
233 { 233 STACK_OF(X509) **chain)
234{
234 X509_STORE_CTX cert_ctx; 235 X509_STORE_CTX cert_ctx;
235 int i; 236 int i;
236 int ret = 1; 237 int ret = 1;
@@ -240,110 +241,115 @@ static int TS_verify_cert(X509_STORE *store, STACK_OF(X509) *untrusted,
240 X509_STORE_CTX_init(&cert_ctx, store, signer, untrusted); 241 X509_STORE_CTX_init(&cert_ctx, store, signer, untrusted);
241 X509_STORE_CTX_set_purpose(&cert_ctx, X509_PURPOSE_TIMESTAMP_SIGN); 242 X509_STORE_CTX_set_purpose(&cert_ctx, X509_PURPOSE_TIMESTAMP_SIGN);
242 i = X509_verify_cert(&cert_ctx); 243 i = X509_verify_cert(&cert_ctx);
243 if (i <= 0) 244 if (i <= 0) {
244 {
245 int j = X509_STORE_CTX_get_error(&cert_ctx); 245 int j = X509_STORE_CTX_get_error(&cert_ctx);
246 TSerr(TS_F_TS_VERIFY_CERT, TS_R_CERTIFICATE_VERIFY_ERROR); 246 TSerr(TS_F_TS_VERIFY_CERT, TS_R_CERTIFICATE_VERIFY_ERROR);
247 ERR_add_error_data(2, "Verify error:", 247 ERR_add_error_data(2, "Verify error:",
248 X509_verify_cert_error_string(j)); 248 X509_verify_cert_error_string(j));
249 ret = 0; 249 ret = 0;
250 } 250 } else {
251 else
252 {
253 /* Get a copy of the certificate chain. */ 251 /* Get a copy of the certificate chain. */
254 *chain = X509_STORE_CTX_get1_chain(&cert_ctx); 252 *chain = X509_STORE_CTX_get1_chain(&cert_ctx);
255 } 253 }
256 254
257 X509_STORE_CTX_cleanup(&cert_ctx); 255 X509_STORE_CTX_cleanup(&cert_ctx);
258 256
259 return ret; 257 return ret;
260 } 258}
261 259
262static int TS_check_signing_certs(PKCS7_SIGNER_INFO *si, STACK_OF(X509) *chain) 260static int
263 { 261TS_check_signing_certs(PKCS7_SIGNER_INFO *si, STACK_OF(X509) *chain)
262{
264 ESS_SIGNING_CERT *ss = ESS_get_signing_cert(si); 263 ESS_SIGNING_CERT *ss = ESS_get_signing_cert(si);
265 STACK_OF(ESS_CERT_ID) *cert_ids = NULL; 264 STACK_OF(ESS_CERT_ID) *cert_ids = NULL;
266 X509 *cert; 265 X509 *cert;
267 int i = 0; 266 int i = 0;
268 int ret = 0; 267 int ret = 0;
269 268
270 if (!ss) goto err; 269 if (!ss)
270 goto err;
271 cert_ids = ss->cert_ids; 271 cert_ids = ss->cert_ids;
272 /* The signer certificate must be the first in cert_ids. */ 272 /* The signer certificate must be the first in cert_ids. */
273 cert = sk_X509_value(chain, 0); 273 cert = sk_X509_value(chain, 0);
274 if (TS_find_cert(cert_ids, cert) != 0) goto err; 274 if (TS_find_cert(cert_ids, cert) != 0)
275 275 goto err;
276
276 /* Check the other certificates of the chain if there are more 277 /* Check the other certificates of the chain if there are more
277 than one certificate ids in cert_ids. */ 278 than one certificate ids in cert_ids. */
278 if (sk_ESS_CERT_ID_num(cert_ids) > 1) 279 if (sk_ESS_CERT_ID_num(cert_ids) > 1) {
279 {
280 /* All the certificates of the chain must be in cert_ids. */ 280 /* All the certificates of the chain must be in cert_ids. */
281 for (i = 1; i < sk_X509_num(chain); ++i) 281 for (i = 1; i < sk_X509_num(chain); ++i) {
282 {
283 cert = sk_X509_value(chain, i); 282 cert = sk_X509_value(chain, i);
284 if (TS_find_cert(cert_ids, cert) < 0) goto err; 283 if (TS_find_cert(cert_ids, cert) < 0)
285 } 284 goto err;
286 } 285 }
286 }
287 ret = 1; 287 ret = 1;
288 err: 288
289err:
289 if (!ret) 290 if (!ret)
290 TSerr(TS_F_TS_CHECK_SIGNING_CERTS, 291 TSerr(TS_F_TS_CHECK_SIGNING_CERTS,
291 TS_R_ESS_SIGNING_CERTIFICATE_ERROR); 292 TS_R_ESS_SIGNING_CERTIFICATE_ERROR);
292 ESS_SIGNING_CERT_free(ss); 293 ESS_SIGNING_CERT_free(ss);
293 return ret; 294 return ret;
294 } 295}
295 296
296static ESS_SIGNING_CERT *ESS_get_signing_cert(PKCS7_SIGNER_INFO *si) 297static ESS_SIGNING_CERT *
297 { 298ESS_get_signing_cert(PKCS7_SIGNER_INFO *si)
299{
298 ASN1_TYPE *attr; 300 ASN1_TYPE *attr;
299 const unsigned char *p; 301 const unsigned char *p;
300 attr = PKCS7_get_signed_attribute(si, 302
301 NID_id_smime_aa_signingCertificate); 303 attr = PKCS7_get_signed_attribute(si,
302 if (!attr) return NULL; 304 NID_id_smime_aa_signingCertificate);
305 if (!attr)
306 return NULL;
303 p = attr->value.sequence->data; 307 p = attr->value.sequence->data;
304 return d2i_ESS_SIGNING_CERT(NULL, &p, attr->value.sequence->length); 308 return d2i_ESS_SIGNING_CERT(NULL, &p, attr->value.sequence->length);
305 } 309}
306 310
307/* Returns < 0 if certificate is not found, certificate index otherwise. */ 311/* Returns < 0 if certificate is not found, certificate index otherwise. */
308static int TS_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert) 312static int
309 { 313TS_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert)
314{
310 int i; 315 int i;
311 316
312 if (!cert_ids || !cert) return -1; 317 if (!cert_ids || !cert)
318 return -1;
313 319
314 /* Recompute SHA1 hash of certificate if necessary (side effect). */ 320 /* Recompute SHA1 hash of certificate if necessary (side effect). */
315 X509_check_purpose(cert, -1, 0); 321 X509_check_purpose(cert, -1, 0);
316 322
317 /* Look for cert in the cert_ids vector. */ 323 /* Look for cert in the cert_ids vector. */
318 for (i = 0; i < sk_ESS_CERT_ID_num(cert_ids); ++i) 324 for (i = 0; i < sk_ESS_CERT_ID_num(cert_ids); ++i) {
319 {
320 ESS_CERT_ID *cid = sk_ESS_CERT_ID_value(cert_ids, i); 325 ESS_CERT_ID *cid = sk_ESS_CERT_ID_value(cert_ids, i);
321 326
322 /* Check the SHA-1 hash first. */ 327 /* Check the SHA-1 hash first. */
323 if (cid->hash->length == sizeof(cert->sha1_hash) 328 if (cid->hash->length == sizeof(cert->sha1_hash) &&
324 && !memcmp(cid->hash->data, cert->sha1_hash, 329 !memcmp(cid->hash->data, cert->sha1_hash,
325 sizeof(cert->sha1_hash))) 330 sizeof(cert->sha1_hash))) {
326 {
327 /* Check the issuer/serial as well if specified. */ 331 /* Check the issuer/serial as well if specified. */
328 ESS_ISSUER_SERIAL *is = cid->issuer_serial; 332 ESS_ISSUER_SERIAL *is = cid->issuer_serial;
329 if (!is || !TS_issuer_serial_cmp(is, cert->cert_info)) 333 if (!is || !TS_issuer_serial_cmp(is, cert->cert_info))
330 return i; 334 return i;
331 }
332 } 335 }
333
334 return -1;
335 } 336 }
336 337
337static int TS_issuer_serial_cmp(ESS_ISSUER_SERIAL *is, X509_CINF *cinfo) 338 return -1;
338 { 339}
340
341static int
342TS_issuer_serial_cmp(ESS_ISSUER_SERIAL *is, X509_CINF *cinfo)
343{
339 GENERAL_NAME *issuer; 344 GENERAL_NAME *issuer;
340 345
341 if (!is || !cinfo || sk_GENERAL_NAME_num(is->issuer) != 1) return -1; 346 if (!is || !cinfo || sk_GENERAL_NAME_num(is->issuer) != 1)
347 return -1;
342 348
343 /* Check the issuer first. It must be a directory name. */ 349 /* Check the issuer first. It must be a directory name. */
344 issuer = sk_GENERAL_NAME_value(is->issuer, 0); 350 issuer = sk_GENERAL_NAME_value(is->issuer, 0);
345 if (issuer->type != GEN_DIRNAME 351 if (issuer->type != GEN_DIRNAME ||
346 || X509_NAME_cmp(issuer->d.dirn, cinfo->issuer)) 352 X509_NAME_cmp(issuer->d.dirn, cinfo->issuer))
347 return -1; 353 return -1;
348 354
349 /* Check the serial number, too. */ 355 /* Check the serial number, too. */
@@ -351,50 +357,54 @@ static int TS_issuer_serial_cmp(ESS_ISSUER_SERIAL *is, X509_CINF *cinfo)
351 return -1; 357 return -1;
352 358
353 return 0; 359 return 0;
354 } 360}
355 361
356/* 362/*
357 * Verifies whether 'response' contains a valid response with regards 363 * Verifies whether 'response' contains a valid response with regards
358 * to the settings of the context: 364 * to the settings of the context:
359 * - Gives an error message if the TS_TST_INFO is not present. 365 * - Gives an error message if the TS_TST_INFO is not present.
360 * - Calls _TS_RESP_verify_token to verify the token content. 366 * - Calls _TS_RESP_verify_token to verify the token content.
361 */ 367 */
362int TS_RESP_verify_response(TS_VERIFY_CTX *ctx, TS_RESP *response) 368int
363 { 369TS_RESP_verify_response(TS_VERIFY_CTX *ctx, TS_RESP *response)
370{
364 PKCS7 *token = TS_RESP_get_token(response); 371 PKCS7 *token = TS_RESP_get_token(response);
365 TS_TST_INFO *tst_info = TS_RESP_get_tst_info(response); 372 TS_TST_INFO *tst_info = TS_RESP_get_tst_info(response);
366 int ret = 0; 373 int ret = 0;
367 374
368 /* Check if we have a successful TS_TST_INFO object in place. */ 375 /* Check if we have a successful TS_TST_INFO object in place. */
369 if (!TS_check_status_info(response)) goto err; 376 if (!TS_check_status_info(response))
377 goto err;
370 378
371 /* Check the contents of the time stamp token. */ 379 /* Check the contents of the time stamp token. */
372 if (!int_TS_RESP_verify_token(ctx, token, tst_info)) 380 if (!int_TS_RESP_verify_token(ctx, token, tst_info))
373 goto err; 381 goto err;
374 382
375 ret = 1; 383 ret = 1;
376 err: 384
385err:
377 return ret; 386 return ret;
378 } 387}
379 388
380/* 389/*
381 * Tries to extract a TS_TST_INFO structure from the PKCS7 token and 390 * Tries to extract a TS_TST_INFO structure from the PKCS7 token and
382 * calls the internal int_TS_RESP_verify_token function for verifying it. 391 * calls the internal int_TS_RESP_verify_token function for verifying it.
383 */ 392 */
384int TS_RESP_verify_token(TS_VERIFY_CTX *ctx, PKCS7 *token) 393int
385 { 394TS_RESP_verify_token(TS_VERIFY_CTX *ctx, PKCS7 *token)
395{
386 TS_TST_INFO *tst_info = PKCS7_to_TS_TST_INFO(token); 396 TS_TST_INFO *tst_info = PKCS7_to_TS_TST_INFO(token);
387 int ret = 0; 397 int ret = 0;
388 if (tst_info) 398
389 { 399 if (tst_info) {
390 ret = int_TS_RESP_verify_token(ctx, token, tst_info); 400 ret = int_TS_RESP_verify_token(ctx, token, tst_info);
391 TS_TST_INFO_free(tst_info); 401 TS_TST_INFO_free(tst_info);
392 }
393 return ret;
394 } 402 }
403 return ret;
404}
395 405
396/* 406/*
397 * Verifies whether the 'token' contains a valid time stamp token 407 * Verifies whether the 'token' contains a valid time stamp token
398 * with regards to the settings of the context. Only those checks are 408 * with regards to the settings of the context. Only those checks are
399 * carried out that are specified in the context: 409 * carried out that are specified in the context:
400 * - Verifies the signature of the TS_TST_INFO. 410 * - Verifies the signature of the TS_TST_INFO.
@@ -405,9 +415,10 @@ int TS_RESP_verify_token(TS_VERIFY_CTX *ctx, PKCS7 *token)
405 * - Check if the TSA name matches the signer. 415 * - Check if the TSA name matches the signer.
406 * - Check if the TSA name is the expected TSA. 416 * - Check if the TSA name is the expected TSA.
407 */ 417 */
408static int int_TS_RESP_verify_token(TS_VERIFY_CTX *ctx, 418static int
409 PKCS7 *token, TS_TST_INFO *tst_info) 419int_TS_RESP_verify_token(TS_VERIFY_CTX *ctx, PKCS7 *token,
410 { 420 TS_TST_INFO *tst_info)
421{
411 X509 *signer = NULL; 422 X509 *signer = NULL;
412 GENERAL_NAME *tsa_name = TS_TST_INFO_get_tsa(tst_info); 423 GENERAL_NAME *tsa_name = TS_TST_INFO_get_tsa(tst_info);
413 X509_ALGOR *md_alg = NULL; 424 X509_ALGOR *md_alg = NULL;
@@ -416,68 +427,66 @@ static int int_TS_RESP_verify_token(TS_VERIFY_CTX *ctx,
416 int ret = 0; 427 int ret = 0;
417 428
418 /* Verify the signature. */ 429 /* Verify the signature. */
419 if ((ctx->flags & TS_VFY_SIGNATURE) 430 if ((ctx->flags & TS_VFY_SIGNATURE) &&
420 && !TS_RESP_verify_signature(token, ctx->certs, ctx->store, 431 !TS_RESP_verify_signature(token, ctx->certs, ctx->store, &signer))
421 &signer))
422 goto err; 432 goto err;
423 433
424 /* Check version number of response. */ 434 /* Check version number of response. */
425 if ((ctx->flags & TS_VFY_VERSION) 435 if ((ctx->flags & TS_VFY_VERSION) &&
426 && TS_TST_INFO_get_version(tst_info) != 1) 436 TS_TST_INFO_get_version(tst_info) != 1) {
427 {
428 TSerr(TS_F_INT_TS_RESP_VERIFY_TOKEN, TS_R_UNSUPPORTED_VERSION); 437 TSerr(TS_F_INT_TS_RESP_VERIFY_TOKEN, TS_R_UNSUPPORTED_VERSION);
429 goto err; 438 goto err;
430 } 439 }
431 440
432 /* Check policies. */ 441 /* Check policies. */
433 if ((ctx->flags & TS_VFY_POLICY) 442 if ((ctx->flags & TS_VFY_POLICY) &&
434 && !TS_check_policy(ctx->policy, tst_info)) 443 !TS_check_policy(ctx->policy, tst_info))
435 goto err; 444 goto err;
436 445
437 /* Check message imprints. */ 446 /* Check message imprints. */
438 if ((ctx->flags & TS_VFY_IMPRINT) 447 if ((ctx->flags & TS_VFY_IMPRINT) &&
439 && !TS_check_imprints(ctx->md_alg, ctx->imprint, ctx->imprint_len, 448 !TS_check_imprints(ctx->md_alg, ctx->imprint, ctx->imprint_len,
440 tst_info)) 449 tst_info))
441 goto err; 450 goto err;
442 451
443 /* Compute and check message imprints. */ 452 /* Compute and check message imprints. */
444 if ((ctx->flags & TS_VFY_DATA) 453 if ((ctx->flags & TS_VFY_DATA) &&
445 && (!TS_compute_imprint(ctx->data, tst_info, 454 (!TS_compute_imprint(ctx->data, tst_info,
446 &md_alg, &imprint, &imprint_len) 455 &md_alg, &imprint, &imprint_len) ||
447 || !TS_check_imprints(md_alg, imprint, imprint_len, tst_info))) 456 !TS_check_imprints(md_alg, imprint, imprint_len, tst_info)))
448 goto err; 457 goto err;
449 458
450 /* Check nonces. */ 459 /* Check nonces. */
451 if ((ctx->flags & TS_VFY_NONCE) 460 if ((ctx->flags & TS_VFY_NONCE) &&
452 && !TS_check_nonces(ctx->nonce, tst_info)) 461 !TS_check_nonces(ctx->nonce, tst_info))
453 goto err; 462 goto err;
454 463
455 /* Check whether TSA name and signer certificate match. */ 464 /* Check whether TSA name and signer certificate match. */
456 if ((ctx->flags & TS_VFY_SIGNER) 465 if ((ctx->flags & TS_VFY_SIGNER) &&
457 && tsa_name && !TS_check_signer_name(tsa_name, signer)) 466 tsa_name && !TS_check_signer_name(tsa_name, signer)) {
458 {
459 TSerr(TS_F_INT_TS_RESP_VERIFY_TOKEN, TS_R_TSA_NAME_MISMATCH); 467 TSerr(TS_F_INT_TS_RESP_VERIFY_TOKEN, TS_R_TSA_NAME_MISMATCH);
460 goto err; 468 goto err;
461 } 469 }
462 470
463 /* Check whether the TSA is the expected one. */ 471 /* Check whether the TSA is the expected one. */
464 if ((ctx->flags & TS_VFY_TSA_NAME) 472 if ((ctx->flags & TS_VFY_TSA_NAME) &&
465 && !TS_check_signer_name(ctx->tsa_name, signer)) 473 !TS_check_signer_name(ctx->tsa_name, signer)) {
466 {
467 TSerr(TS_F_INT_TS_RESP_VERIFY_TOKEN, TS_R_TSA_UNTRUSTED); 474 TSerr(TS_F_INT_TS_RESP_VERIFY_TOKEN, TS_R_TSA_UNTRUSTED);
468 goto err; 475 goto err;
469 } 476 }
470 477
471 ret = 1; 478 ret = 1;
472 err: 479
480err:
473 X509_free(signer); 481 X509_free(signer);
474 X509_ALGOR_free(md_alg); 482 X509_ALGOR_free(md_alg);
475 free(imprint); 483 free(imprint);
476 return ret; 484 return ret;
477 } 485}
478 486
479static int TS_check_status_info(TS_RESP *response) 487static int
480 { 488TS_check_status_info(TS_RESP *response)
489{
481 TS_STATUS_INFO *info = TS_RESP_get_status_info(response); 490 TS_STATUS_INFO *info = TS_RESP_get_status_info(response);
482 long status = ASN1_INTEGER_get(info->status); 491 long status = ASN1_INTEGER_get(info->status);
483 const char *status_text = NULL; 492 const char *status_text = NULL;
@@ -485,7 +494,8 @@ static int TS_check_status_info(TS_RESP *response)
485 char failure_text[TS_STATUS_BUF_SIZE] = ""; 494 char failure_text[TS_STATUS_BUF_SIZE] = "";
486 495
487 /* Check if everything went fine. */ 496 /* Check if everything went fine. */
488 if (status == 0 || status == 1) return 1; 497 if (status == 0 || status == 1)
498 return 1;
489 499
490 /* There was an error, get the description in status_text. */ 500 /* There was an error, get the description in status_text. */
491 if (0 <= status && status < (long)TS_STATUS_TEXT_SIZE) 501 if (0 <= status && status < (long)TS_STATUS_TEXT_SIZE)
@@ -494,93 +504,88 @@ static int TS_check_status_info(TS_RESP *response)
494 status_text = "unknown code"; 504 status_text = "unknown code";
495 505
496 /* Set the embedded_status_text to the returned description. */ 506 /* Set the embedded_status_text to the returned description. */
497 if (sk_ASN1_UTF8STRING_num(info->text) > 0 507 if (sk_ASN1_UTF8STRING_num(info->text) > 0 &&
498 && !(embedded_status_text = TS_get_status_text(info->text))) 508 !(embedded_status_text = TS_get_status_text(info->text)))
499 return 0; 509 return 0;
500 510
501 /* Filling in failure_text with the failure information. */ 511 /* Filling in failure_text with the failure information. */
502 if (info->failure_info) 512 if (info->failure_info) {
503 {
504 int i; 513 int i;
505 int first = 1; 514 int first = 1;
506 for (i = 0; i < (int)TS_FAILURE_INFO_SIZE; ++i) 515 for (i = 0; i < (int)TS_FAILURE_INFO_SIZE; ++i) {
507 {
508 if (ASN1_BIT_STRING_get_bit(info->failure_info, 516 if (ASN1_BIT_STRING_get_bit(info->failure_info,
509 TS_failure_info[i].code)) 517 TS_failure_info[i].code)) {
510 {
511 if (!first) 518 if (!first)
512 strlcat(failure_text, ",", 519 strlcat(failure_text, ",",
513 TS_STATUS_BUF_SIZE); 520 TS_STATUS_BUF_SIZE);
514 else 521 else
515 first = 0; 522 first = 0;
516 strlcat(failure_text, TS_failure_info[i].text, 523 strlcat(failure_text, TS_failure_info[i].text,
517 TS_STATUS_BUF_SIZE); 524 TS_STATUS_BUF_SIZE);
518 }
519 } 525 }
520 } 526 }
527 }
521 if (failure_text[0] == '\0') 528 if (failure_text[0] == '\0')
522 strlcpy(failure_text, "unspecified", TS_STATUS_BUF_SIZE); 529 strlcpy(failure_text, "unspecified", TS_STATUS_BUF_SIZE);
523 530
524 /* Making up the error string. */ 531 /* Making up the error string. */
525 TSerr(TS_F_TS_CHECK_STATUS_INFO, TS_R_NO_TIME_STAMP_TOKEN); 532 TSerr(TS_F_TS_CHECK_STATUS_INFO, TS_R_NO_TIME_STAMP_TOKEN);
526 ERR_add_error_data(6, 533 ERR_add_error_data(6,
527 "status code: ", status_text, 534 "status code: ", status_text,
528 ", status text: ", embedded_status_text ? 535 ", status text: ", embedded_status_text ?
529 embedded_status_text : "unspecified", 536 embedded_status_text : "unspecified",
530 ", failure codes: ", failure_text); 537 ", failure codes: ", failure_text);
531 free(embedded_status_text); 538 free(embedded_status_text);
532 539
533 return 0; 540 return 0;
534 } 541}
535 542
536static char *TS_get_status_text(STACK_OF(ASN1_UTF8STRING) *text) 543static char *
537 { 544TS_get_status_text(STACK_OF(ASN1_UTF8STRING) *text)
545{
538 int i; 546 int i;
539 unsigned int length = 0; 547 unsigned int length = 0;
540 char *result = NULL; 548 char *result = NULL;
541 549
542 /* Determine length first. */ 550 /* Determine length first. */
543 for (i = 0; i < sk_ASN1_UTF8STRING_num(text); ++i) 551 for (i = 0; i < sk_ASN1_UTF8STRING_num(text); ++i) {
544 {
545 ASN1_UTF8STRING *current = sk_ASN1_UTF8STRING_value(text, i); 552 ASN1_UTF8STRING *current = sk_ASN1_UTF8STRING_value(text, i);
546 length += ASN1_STRING_length(current); 553 length += ASN1_STRING_length(current);
547 length += 1; /* separator character */ 554 length += 1; /* separator character */
548 } 555 }
549 /* Allocate memory (closing '\0' included). */ 556 /* Allocate memory (closing '\0' included). */
550 if (!(result = malloc(length))) 557 if (!(result = malloc(length))) {
551 {
552 TSerr(TS_F_TS_GET_STATUS_TEXT, ERR_R_MALLOC_FAILURE); 558 TSerr(TS_F_TS_GET_STATUS_TEXT, ERR_R_MALLOC_FAILURE);
553 return NULL; 559 return NULL;
554 } 560 }
555 /* Concatenate the descriptions. */ 561 /* Concatenate the descriptions. */
556 result[0] = '\0'; 562 result[0] = '\0';
557 for (i = 0; i < sk_ASN1_UTF8STRING_num(text); ++i) 563 for (i = 0; i < sk_ASN1_UTF8STRING_num(text); ++i) {
558 {
559 ASN1_UTF8STRING *current = sk_ASN1_UTF8STRING_value(text, i); 564 ASN1_UTF8STRING *current = sk_ASN1_UTF8STRING_value(text, i);
560 if (i > 0) 565 if (i > 0)
561 strlcat(result, "/", length); 566 strlcat(result, "/", length);
562 strlcat(result, ASN1_STRING_data(current), length); 567 strlcat(result, ASN1_STRING_data(current), length);
563 }
564 return result;
565 } 568 }
569 return result;
570}
566 571
567static int TS_check_policy(ASN1_OBJECT *req_oid, TS_TST_INFO *tst_info) 572static int
568 { 573TS_check_policy(ASN1_OBJECT *req_oid, TS_TST_INFO *tst_info)
574{
569 ASN1_OBJECT *resp_oid = TS_TST_INFO_get_policy_id(tst_info); 575 ASN1_OBJECT *resp_oid = TS_TST_INFO_get_policy_id(tst_info);
570 576
571 if (OBJ_cmp(req_oid, resp_oid) != 0) 577 if (OBJ_cmp(req_oid, resp_oid) != 0) {
572 {
573 TSerr(TS_F_TS_CHECK_POLICY, TS_R_POLICY_MISMATCH); 578 TSerr(TS_F_TS_CHECK_POLICY, TS_R_POLICY_MISMATCH);
574 return 0; 579 return 0;
575 } 580 }
576 581
577 return 1; 582 return 1;
578 } 583}
579 584
580static int TS_compute_imprint(BIO *data, TS_TST_INFO *tst_info, 585static int
581 X509_ALGOR **md_alg, 586TS_compute_imprint(BIO *data, TS_TST_INFO *tst_info, X509_ALGOR **md_alg,
582 unsigned char **imprint, unsigned *imprint_len) 587 unsigned char **imprint, unsigned *imprint_len)
583 { 588{
584 TS_MSG_IMPRINT *msg_imprint = TS_TST_INFO_get_msg_imprint(tst_info); 589 TS_MSG_IMPRINT *msg_imprint = TS_TST_INFO_get_msg_imprint(tst_info);
585 X509_ALGOR *md_alg_resp = TS_MSG_IMPRINT_get_algo(msg_imprint); 590 X509_ALGOR *md_alg_resp = TS_MSG_IMPRINT_get_algo(msg_imprint);
586 const EVP_MD *md; 591 const EVP_MD *md;
@@ -592,136 +597,136 @@ static int TS_compute_imprint(BIO *data, TS_TST_INFO *tst_info,
592 *imprint = NULL; 597 *imprint = NULL;
593 598
594 /* Return the MD algorithm of the response. */ 599 /* Return the MD algorithm of the response. */
595 if (!(*md_alg = X509_ALGOR_dup(md_alg_resp))) goto err; 600 if (!(*md_alg = X509_ALGOR_dup(md_alg_resp)))
601 goto err;
596 602
597 /* Getting the MD object. */ 603 /* Getting the MD object. */
598 if (!(md = EVP_get_digestbyobj((*md_alg)->algorithm))) 604 if (!(md = EVP_get_digestbyobj((*md_alg)->algorithm))) {
599 {
600 TSerr(TS_F_TS_COMPUTE_IMPRINT, TS_R_UNSUPPORTED_MD_ALGORITHM); 605 TSerr(TS_F_TS_COMPUTE_IMPRINT, TS_R_UNSUPPORTED_MD_ALGORITHM);
601 goto err; 606 goto err;
602 } 607 }
603 608
604 /* Compute message digest. */ 609 /* Compute message digest. */
605 length = EVP_MD_size(md); 610 length = EVP_MD_size(md);
606 if (length < 0) 611 if (length < 0)
607 goto err; 612 goto err;
608 *imprint_len = length; 613 *imprint_len = length;
609 if (!(*imprint = malloc(*imprint_len))) 614 if (!(*imprint = malloc(*imprint_len))) {
610 {
611 TSerr(TS_F_TS_COMPUTE_IMPRINT, ERR_R_MALLOC_FAILURE); 615 TSerr(TS_F_TS_COMPUTE_IMPRINT, ERR_R_MALLOC_FAILURE);
612 goto err; 616 goto err;
613 } 617 }
614 618
615 if (!EVP_DigestInit(&md_ctx, md)) 619 if (!EVP_DigestInit(&md_ctx, md))
616 goto err; 620 goto err;
617 while ((length = BIO_read(data, buffer, sizeof(buffer))) > 0) 621 while ((length = BIO_read(data, buffer, sizeof(buffer))) > 0) {
618 {
619 if (!EVP_DigestUpdate(&md_ctx, buffer, length)) 622 if (!EVP_DigestUpdate(&md_ctx, buffer, length))
620 goto err; 623 goto err;
621 } 624 }
622 if (!EVP_DigestFinal(&md_ctx, *imprint, NULL)) 625 if (!EVP_DigestFinal(&md_ctx, *imprint, NULL))
623 goto err; 626 goto err;
624 627
625 return 1; 628 return 1;
626 err: 629
630err:
627 X509_ALGOR_free(*md_alg); 631 X509_ALGOR_free(*md_alg);
628 free(*imprint); 632 free(*imprint);
629 *imprint = NULL; 633 *imprint = NULL;
630 *imprint_len = 0; 634 *imprint_len = 0;
631 return 0; 635 return 0;
632 } 636}
633 637
634static int TS_check_imprints(X509_ALGOR *algor_a, 638static int
635 unsigned char *imprint_a, unsigned len_a, 639TS_check_imprints(X509_ALGOR *algor_a, unsigned char *imprint_a, unsigned len_a,
636 TS_TST_INFO *tst_info) 640 TS_TST_INFO *tst_info)
637 { 641{
638 TS_MSG_IMPRINT *b = TS_TST_INFO_get_msg_imprint(tst_info); 642 TS_MSG_IMPRINT *b = TS_TST_INFO_get_msg_imprint(tst_info);
639 X509_ALGOR *algor_b = TS_MSG_IMPRINT_get_algo(b); 643 X509_ALGOR *algor_b = TS_MSG_IMPRINT_get_algo(b);
640 int ret = 0; 644 int ret = 0;
641 645
642 /* algor_a is optional. */ 646 /* algor_a is optional. */
643 if (algor_a) 647 if (algor_a) {
644 {
645 /* Compare algorithm OIDs. */ 648 /* Compare algorithm OIDs. */
646 if (OBJ_cmp(algor_a->algorithm, algor_b->algorithm)) goto err; 649 if (OBJ_cmp(algor_a->algorithm, algor_b->algorithm))
650 goto err;
647 651
648 /* The parameter must be NULL in both. */ 652 /* The parameter must be NULL in both. */
649 if ((algor_a->parameter 653 if ((algor_a->parameter &&
650 && ASN1_TYPE_get(algor_a->parameter) != V_ASN1_NULL) 654 ASN1_TYPE_get(algor_a->parameter) != V_ASN1_NULL) ||
651 || (algor_b->parameter 655 (algor_b->parameter &&
652 && ASN1_TYPE_get(algor_b->parameter) != V_ASN1_NULL)) 656 ASN1_TYPE_get(algor_b->parameter) != V_ASN1_NULL))
653 goto err; 657 goto err;
654 } 658 }
655 659
656 /* Compare octet strings. */ 660 /* Compare octet strings. */
657 ret = len_a == (unsigned) ASN1_STRING_length(b->hashed_msg) && 661 ret = len_a == (unsigned) ASN1_STRING_length(b->hashed_msg) &&
658 memcmp(imprint_a, ASN1_STRING_data(b->hashed_msg), len_a) == 0; 662 memcmp(imprint_a, ASN1_STRING_data(b->hashed_msg), len_a) == 0;
659 err: 663
664err:
660 if (!ret) 665 if (!ret)
661 TSerr(TS_F_TS_CHECK_IMPRINTS, TS_R_MESSAGE_IMPRINT_MISMATCH); 666 TSerr(TS_F_TS_CHECK_IMPRINTS, TS_R_MESSAGE_IMPRINT_MISMATCH);
662 return ret; 667 return ret;
663 } 668}
664 669
665static int TS_check_nonces(const ASN1_INTEGER *a, TS_TST_INFO *tst_info) 670static int
666 { 671TS_check_nonces(const ASN1_INTEGER *a, TS_TST_INFO *tst_info)
672{
667 const ASN1_INTEGER *b = TS_TST_INFO_get_nonce(tst_info); 673 const ASN1_INTEGER *b = TS_TST_INFO_get_nonce(tst_info);
668 674
669 /* Error if nonce is missing. */ 675 /* Error if nonce is missing. */
670 if (!b) 676 if (!b) {
671 {
672 TSerr(TS_F_TS_CHECK_NONCES, TS_R_NONCE_NOT_RETURNED); 677 TSerr(TS_F_TS_CHECK_NONCES, TS_R_NONCE_NOT_RETURNED);
673 return 0; 678 return 0;
674 } 679 }
675 680
676 /* No error if a nonce is returned without being requested. */ 681 /* No error if a nonce is returned without being requested. */
677 if (ASN1_INTEGER_cmp(a, b) != 0) 682 if (ASN1_INTEGER_cmp(a, b) != 0) {
678 {
679 TSerr(TS_F_TS_CHECK_NONCES, TS_R_NONCE_MISMATCH); 683 TSerr(TS_F_TS_CHECK_NONCES, TS_R_NONCE_MISMATCH);
680 return 0; 684 return 0;
681 } 685 }
682 686
683 return 1; 687 return 1;
684 } 688}
685 689
686/* Check if the specified TSA name matches either the subject 690/* Check if the specified TSA name matches either the subject
687 or one of the subject alternative names of the TSA certificate. */ 691 or one of the subject alternative names of the TSA certificate. */
688static int TS_check_signer_name(GENERAL_NAME *tsa_name, X509 *signer) 692static int
689 { 693TS_check_signer_name(GENERAL_NAME *tsa_name, X509 *signer)
694{
690 STACK_OF(GENERAL_NAME) *gen_names = NULL; 695 STACK_OF(GENERAL_NAME) *gen_names = NULL;
691 int idx = -1; 696 int idx = -1;
692 int found = 0; 697 int found = 0;
693 698
694 /* Check the subject name first. */ 699 /* Check the subject name first. */
695 if (tsa_name->type == GEN_DIRNAME 700 if (tsa_name->type == GEN_DIRNAME &&
696 && X509_name_cmp(tsa_name->d.dirn, signer->cert_info->subject) == 0) 701 X509_name_cmp(tsa_name->d.dirn, signer->cert_info->subject) == 0)
697 return 1; 702 return 1;
698 703
699 /* Check all the alternative names. */ 704 /* Check all the alternative names. */
700 gen_names = X509_get_ext_d2i(signer, NID_subject_alt_name, 705 gen_names = X509_get_ext_d2i(signer, NID_subject_alt_name,
701 NULL, &idx); 706 NULL, &idx);
702 while (gen_names != NULL 707 while (gen_names != NULL &&
703 && !(found = TS_find_name(gen_names, tsa_name) >= 0)) 708 !(found = TS_find_name(gen_names, tsa_name) >= 0)) {
704 {
705 /* Get the next subject alternative name, 709 /* Get the next subject alternative name,
706 although there should be no more than one. */ 710 although there should be no more than one. */
707 GENERAL_NAMES_free(gen_names); 711 GENERAL_NAMES_free(gen_names);
708 gen_names = X509_get_ext_d2i(signer, NID_subject_alt_name, 712 gen_names = X509_get_ext_d2i(signer, NID_subject_alt_name,
709 NULL, &idx); 713 NULL, &idx);
710 }
711 if (gen_names) GENERAL_NAMES_free(gen_names);
712
713 return found;
714 } 714 }
715 if (gen_names)
716 GENERAL_NAMES_free(gen_names);
717
718 return found;
719}
715 720
716/* Returns 1 if name is in gen_names, 0 otherwise. */ 721/* Returns 1 if name is in gen_names, 0 otherwise. */
717static int TS_find_name(STACK_OF(GENERAL_NAME) *gen_names, GENERAL_NAME *name) 722static int
718 { 723TS_find_name(STACK_OF(GENERAL_NAME) *gen_names, GENERAL_NAME *name)
724{
719 int i, found; 725 int i, found;
720 for (i = 0, found = 0; !found && i < sk_GENERAL_NAME_num(gen_names); 726 for (i = 0, found = 0; !found && i < sk_GENERAL_NAME_num(gen_names);
721 ++i) 727 ++i) {
722 {
723 GENERAL_NAME *current = sk_GENERAL_NAME_value(gen_names, i); 728 GENERAL_NAME *current = sk_GENERAL_NAME_value(gen_names, i);
724 found = GENERAL_NAME_cmp(current, name) == 0; 729 found = GENERAL_NAME_cmp(current, name) == 0;
725 }
726 return found ? i - 1 : -1;
727 } 730 }
731 return found ? i - 1 : -1;
732}