Bug Summary

File:out/../deps/openssl/openssl/crypto/ts/ts_rsp_verify.c
Warning:line 143, column 13
Although the value stored to 'i' is used in the enclosing expression, the value is never actually read from 'i'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name ts_rsp_verify.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/home/maurizio/node-v18.6.0/out -resource-dir /usr/local/lib/clang/16.0.0 -D V8_DEPRECATION_WARNINGS -D V8_IMMINENT_DEPRECATION_WARNINGS -D _GLIBCXX_USE_CXX11_ABI=1 -D NODE_OPENSSL_CONF_NAME=nodejs_conf -D NODE_OPENSSL_HAS_QUIC -D __STDC_FORMAT_MACROS -D OPENSSL_NO_PINSHARED -D OPENSSL_THREADS -D OPENSSL_NO_HW -D OPENSSL_API_COMPAT=0x10100001L -D STATIC_LEGACY -D NDEBUG -D OPENSSL_USE_NODELETE -D L_ENDIAN -D OPENSSL_BUILDING_OPENSSL -D AES_ASM -D BSAES_ASM -D CMLL_ASM -D ECP_NISTZ256_ASM -D GHASH_ASM -D KECCAK1600_ASM -D MD5_ASM -D OPENSSL_BN_ASM_GF2m -D OPENSSL_BN_ASM_MONT -D OPENSSL_BN_ASM_MONT5 -D OPENSSL_CPUID_OBJ -D OPENSSL_IA32_SSE2 -D PADLOCK_ASM -D POLY1305_ASM -D SHA1_ASM -D SHA256_ASM -D SHA512_ASM -D VPAES_ASM -D WHIRLPOOL_ASM -D X25519_ASM -D OPENSSL_PIC -D MODULESDIR="/home/maurizio/node-v18.6.0/out/Release/obj.target/deps/openssl/lib/openssl-modules" -D OPENSSLDIR="/home/maurizio/node-v18.6.0/out/Release/obj.target/deps/openssl" -D OPENSSLDIR="/etc/ssl" -D ENGINESDIR="/dev/null" -D TERMIOS -I ../deps/openssl/openssl -I ../deps/openssl/openssl/include -I ../deps/openssl/openssl/crypto -I ../deps/openssl/openssl/crypto/include -I ../deps/openssl/openssl/crypto/modes -I ../deps/openssl/openssl/crypto/ec/curve448 -I ../deps/openssl/openssl/crypto/ec/curve448/arch_32 -I ../deps/openssl/openssl/providers/common/include -I ../deps/openssl/openssl/providers/implementations/include -I ../deps/openssl/config -I ../deps/openssl/config/archs/linux-x86_64/asm -I ../deps/openssl/config/archs/linux-x86_64/asm/include -I ../deps/openssl/config/archs/linux-x86_64/asm/crypto -I ../deps/openssl/config/archs/linux-x86_64/asm/crypto/include/internal -I ../deps/openssl/config/archs/linux-x86_64/asm/providers/common/include -internal-isystem /usr/local/lib/clang/16.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-redhat-linux/8/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O3 -Wno-unused-parameter -Wno-missing-field-initializers -Wno-old-style-declaration -fdebug-compilation-dir=/home/maurizio/node-v18.6.0/out -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2022-08-22-142216-507842-1 -x c ../deps/openssl/openssl/crypto/ts/ts_rsp_verify.c
1/*
2 * Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10#include <stdio.h>
11#include <openssl/objects.h>
12#include <openssl/ts.h>
13#include <openssl/pkcs7.h>
14#include "internal/cryptlib.h"
15#include "internal/sizes.h"
16#include "crypto/ess.h"
17#include "ts_local.h"
18
19static int ts_verify_cert(X509_STORE *store, STACK_OF(X509)struct stack_st_X509 *untrusted,
20 X509 *signer, STACK_OF(X509)struct stack_st_X509 **chain);
21static int ts_check_signing_certs(const PKCS7_SIGNER_INFO *si,
22 const STACK_OF(X509)struct stack_st_X509 *chain);
23
24static int int_ts_RESP_verify_token(TS_VERIFY_CTX *ctx,
25 PKCS7 *token, TS_TST_INFO *tst_info);
26static int ts_check_status_info(TS_RESP *response);
27static char *ts_get_status_text(STACK_OF(ASN1_UTF8STRING)struct stack_st_ASN1_UTF8STRING *text);
28static int ts_check_policy(const ASN1_OBJECT *req_oid,
29 const TS_TST_INFO *tst_info);
30static int ts_compute_imprint(BIO *data, TS_TST_INFO *tst_info,
31 X509_ALGOR **md_alg,
32 unsigned char **imprint, unsigned *imprint_len);
33static int ts_check_imprints(X509_ALGOR *algor_a,
34 const unsigned char *imprint_a, unsigned len_a,
35 TS_TST_INFO *tst_info);
36static int ts_check_nonces(const ASN1_INTEGER *a, TS_TST_INFO *tst_info);
37static int ts_check_signer_name(GENERAL_NAME *tsa_name, X509 *signer);
38static int ts_find_name(STACK_OF(GENERAL_NAME)struct stack_st_GENERAL_NAME *gen_names,
39 GENERAL_NAME *name);
40
41/*
42 * This must be large enough to hold all values in ts_status_text (with
43 * comma separator) or all text fields in ts_failure_info (also with comma).
44 */
45#define TS_STATUS_BUF_SIZE256 256
46
47/*
48 * Local mapping between response codes and descriptions.
49 */
50static const char *ts_status_text[] = {
51 "granted",
52 "grantedWithMods",
53 "rejection",
54 "waiting",
55 "revocationWarning",
56 "revocationNotification"
57};
58
59#define TS_STATUS_TEXT_SIZE(sizeof(ts_status_text)/sizeof((ts_status_text)[0])) OSSL_NELEM(ts_status_text)(sizeof(ts_status_text)/sizeof((ts_status_text)[0]))
60
61static struct {
62 int code;
63 const char *text;
64} ts_failure_info[] = {
65 {TS_INFO_BAD_ALG0, "badAlg"},
66 {TS_INFO_BAD_REQUEST2, "badRequest"},
67 {TS_INFO_BAD_DATA_FORMAT5, "badDataFormat"},
68 {TS_INFO_TIME_NOT_AVAILABLE14, "timeNotAvailable"},
69 {TS_INFO_UNACCEPTED_POLICY15, "unacceptedPolicy"},
70 {TS_INFO_UNACCEPTED_EXTENSION16, "unacceptedExtension"},
71 {TS_INFO_ADD_INFO_NOT_AVAILABLE17, "addInfoNotAvailable"},
72 {TS_INFO_SYSTEM_FAILURE25, "systemFailure"}
73};
74
75
76/*-
77 * This function carries out the following tasks:
78 * - Checks if there is one and only one signer.
79 * - Search for the signing certificate in 'certs' and in the response.
80 * - Check the extended key usage and key usage fields of the signer
81 * certificate (done by the path validation).
82 * - Build and validate the certificate path.
83 * - Check if the certificate path meets the requirements of the
84 * SigningCertificate ESS signed attribute.
85 * - Verify the signature value.
86 * - Returns the signer certificate in 'signer', if 'signer' is not NULL.
87 */
88int TS_RESP_verify_signature(PKCS7 *token, STACK_OF(X509)struct stack_st_X509 *certs,
89 X509_STORE *store, X509 **signer_out)
90{
91 STACK_OF(PKCS7_SIGNER_INFO)struct stack_st_PKCS7_SIGNER_INFO *sinfos = NULL((void*)0);
92 PKCS7_SIGNER_INFO *si;
93 STACK_OF(X509)struct stack_st_X509 *untrusted = NULL((void*)0);
94 STACK_OF(X509)struct stack_st_X509 *signers = NULL((void*)0);
95 X509 *signer;
96 STACK_OF(X509)struct stack_st_X509 *chain = NULL((void*)0);
97 char buf[4096];
98 int i, j = 0, ret = 0;
99 BIO *p7bio = NULL((void*)0);
100
101 /* Some sanity checks first. */
102 if (!token) {
103 ERR_raise(ERR_LIB_TS, TS_R_INVALID_NULL_POINTER)(ERR_new(), ERR_set_debug("../deps/openssl/openssl/crypto/ts/ts_rsp_verify.c"
,103,__func__), ERR_set_error)((47),(102),((void*)0))
;
104 goto err;
105 }
106 if (!PKCS7_type_is_signed(token)(OBJ_obj2nid((token)->type) == 22)) {
107 ERR_raise(ERR_LIB_TS, TS_R_WRONG_CONTENT_TYPE)(ERR_new(), ERR_set_debug("../deps/openssl/openssl/crypto/ts/ts_rsp_verify.c"
,107,__func__), ERR_set_error)((47),(114),((void*)0))
;
108 goto err;
109 }
110 sinfos = PKCS7_get_signer_info(token);
111 if (!sinfos || sk_PKCS7_SIGNER_INFO_num(sinfos)OPENSSL_sk_num(ossl_check_const_PKCS7_SIGNER_INFO_sk_type(sinfos
))
!= 1) {
112 ERR_raise(ERR_LIB_TS, TS_R_THERE_MUST_BE_ONE_SIGNER)(ERR_new(), ERR_set_debug("../deps/openssl/openssl/crypto/ts/ts_rsp_verify.c"
,112,__func__), ERR_set_error)((47),(110),((void*)0))
;
113 goto err;
114 }
115 si = sk_PKCS7_SIGNER_INFO_value(sinfos, 0)((PKCS7_SIGNER_INFO *)OPENSSL_sk_value(ossl_check_const_PKCS7_SIGNER_INFO_sk_type
(sinfos), (0)))
;
116 if (PKCS7_get_detached(token)PKCS7_ctrl(token,2,0,((void*)0))) {
117 ERR_raise(ERR_LIB_TS, TS_R_NO_CONTENT)(ERR_new(), ERR_set_debug("../deps/openssl/openssl/crypto/ts/ts_rsp_verify.c"
,117,__func__), ERR_set_error)((47),(106),((void*)0))
;
118 goto err;
119 }
120
121 /*
122 * Get hold of the signer certificate, search only internal certificates
123 * if it was requested.
124 */
125 signers = PKCS7_get0_signers(token, certs, 0);
126 if (!signers || sk_X509_num(signers)OPENSSL_sk_num(ossl_check_const_X509_sk_type(signers)) != 1)
127 goto err;
128 signer = sk_X509_value(signers, 0)((X509 *)OPENSSL_sk_value(ossl_check_const_X509_sk_type(signers
), (0)))
;
129
130 untrusted = sk_X509_new_reserve(NULL, sk_X509_num(certs)((struct stack_st_X509 *)OPENSSL_sk_new_reserve(ossl_check_X509_compfunc_type
(((void*)0)), (OPENSSL_sk_num(ossl_check_const_X509_sk_type(certs
)) + OPENSSL_sk_num(ossl_check_const_X509_sk_type(token->d
.sign->cert)))))
131 + sk_X509_num(token->d.sign->cert))((struct stack_st_X509 *)OPENSSL_sk_new_reserve(ossl_check_X509_compfunc_type
(((void*)0)), (OPENSSL_sk_num(ossl_check_const_X509_sk_type(certs
)) + OPENSSL_sk_num(ossl_check_const_X509_sk_type(token->d
.sign->cert)))))
;
132 if (untrusted == NULL((void*)0)
133 || !X509_add_certs(untrusted, certs, 0)
134 || !X509_add_certs(untrusted, token->d.sign->cert, 0))
135 goto err;
136 if (!ts_verify_cert(store, untrusted, signer, &chain))
137 goto err;
138 if (!ts_check_signing_certs(si, chain))
139 goto err;
140 p7bio = PKCS7_dataInit(token, NULL((void*)0));
141
142 /* We now have to 'read' from p7bio to calculate digests etc. */
143 while ((i = BIO_read(p7bio, buf, sizeof(buf))) > 0)
Although the value stored to 'i' is used in the enclosing expression, the value is never actually read from 'i'
144 continue;
145
146 j = PKCS7_signatureVerify(p7bio, token, si, signer);
147 if (j <= 0) {
148 ERR_raise(ERR_LIB_TS, TS_R_SIGNATURE_FAILURE)(ERR_new(), ERR_set_debug("../deps/openssl/openssl/crypto/ts/ts_rsp_verify.c"
,148,__func__), ERR_set_error)((47),(109),((void*)0))
;
149 goto err;
150 }
151
152 if (signer_out) {
153 *signer_out = signer;
154 X509_up_ref(signer);
155 }
156 ret = 1;
157
158 err:
159 BIO_free_all(p7bio);
160 sk_X509_free(untrusted)OPENSSL_sk_free(ossl_check_X509_sk_type(untrusted));
161 sk_X509_pop_free(chain, X509_free)OPENSSL_sk_pop_free(ossl_check_X509_sk_type(chain),ossl_check_X509_freefunc_type
(X509_free))
;
162 sk_X509_free(signers)OPENSSL_sk_free(ossl_check_X509_sk_type(signers));
163
164 return ret;
165}
166
167/*
168 * The certificate chain is returned in chain. Caller is responsible for
169 * freeing the vector.
170 */
171static int ts_verify_cert(X509_STORE *store, STACK_OF(X509)struct stack_st_X509 *untrusted,
172 X509 *signer, STACK_OF(X509)struct stack_st_X509 **chain)
173{
174 X509_STORE_CTX *cert_ctx = NULL((void*)0);
175 int i;
176 int ret = 0;
177
178 *chain = NULL((void*)0);
179 cert_ctx = X509_STORE_CTX_new();
180 if (cert_ctx == NULL((void*)0)) {
181 ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE)(ERR_new(), ERR_set_debug("../deps/openssl/openssl/crypto/ts/ts_rsp_verify.c"
,181,__func__), ERR_set_error)((47),((256|((0x1 << 18L)
|(0x2 << 18L)))),((void*)0))
;
182 goto err;
183 }
184 if (!X509_STORE_CTX_init(cert_ctx, store, signer, untrusted))
185 goto end;
186 X509_STORE_CTX_set_purpose(cert_ctx, X509_PURPOSE_TIMESTAMP_SIGN9);
187 i = X509_verify_cert(cert_ctx);
188 if (i <= 0) {
189 int j = X509_STORE_CTX_get_error(cert_ctx);
190 ERR_raise_data(ERR_new(), ERR_set_debug("../deps/openssl/openssl/crypto/ts/ts_rsp_verify.c"
,190,__func__), ERR_set_error)
(ERR_LIB_TS47, TS_R_CERTIFICATE_VERIFY_ERROR100,
191 "Verify error:%s", X509_verify_cert_error_string(j));
192 goto err;
193 }
194 *chain = X509_STORE_CTX_get1_chain(cert_ctx);
195 ret = 1;
196 goto end;
197
198err:
199 ret = 0;
200
201end:
202 X509_STORE_CTX_free(cert_ctx);
203 return ret;
204}
205
206static ESS_SIGNING_CERT *ossl_ess_get_signing_cert(const PKCS7_SIGNER_INFO *si)
207{
208 ASN1_TYPE *attr;
209 const unsigned char *p;
210
211 attr = PKCS7_get_signed_attribute(si, NID_id_smime_aa_signingCertificate223);
212 if (attr == NULL((void*)0))
213 return NULL((void*)0);
214 p = attr->value.sequence->data;
215 return d2i_ESS_SIGNING_CERT(NULL((void*)0), &p, attr->value.sequence->length);
216}
217
218static
219ESS_SIGNING_CERT_V2 *ossl_ess_get_signing_cert_v2(const PKCS7_SIGNER_INFO *si)
220{
221 ASN1_TYPE *attr;
222 const unsigned char *p;
223
224 attr = PKCS7_get_signed_attribute(si, NID_id_smime_aa_signingCertificateV21086);
225 if (attr == NULL((void*)0))
226 return NULL((void*)0);
227 p = attr->value.sequence->data;
228 return d2i_ESS_SIGNING_CERT_V2(NULL((void*)0), &p, attr->value.sequence->length);
229}
230
231static int ts_check_signing_certs(const PKCS7_SIGNER_INFO *si,
232 const STACK_OF(X509)struct stack_st_X509 *chain)
233{
234 ESS_SIGNING_CERT *ss = ossl_ess_get_signing_cert(si);
235 ESS_SIGNING_CERT_V2 *ssv2 = ossl_ess_get_signing_cert_v2(si);
236 int ret = OSSL_ESS_check_signing_certs(ss, ssv2, chain, 1) > 0;
237
238 ESS_SIGNING_CERT_free(ss);
239 ESS_SIGNING_CERT_V2_free(ssv2);
240 return ret;
241}
242
243/*-
244 * Verifies whether 'response' contains a valid response with regards
245 * to the settings of the context:
246 * - Gives an error message if the TS_TST_INFO is not present.
247 * - Calls _TS_RESP_verify_token to verify the token content.
248 */
249int TS_RESP_verify_response(TS_VERIFY_CTX *ctx, TS_RESP *response)
250{
251 PKCS7 *token = response->token;
252 TS_TST_INFO *tst_info = response->tst_info;
253 int ret = 0;
254
255 if (!ts_check_status_info(response))
256 goto err;
257 if (!int_ts_RESP_verify_token(ctx, token, tst_info))
258 goto err;
259 ret = 1;
260
261 err:
262 return ret;
263}
264
265/*
266 * Tries to extract a TS_TST_INFO structure from the PKCS7 token and
267 * calls the internal int_TS_RESP_verify_token function for verifying it.
268 */
269int TS_RESP_verify_token(TS_VERIFY_CTX *ctx, PKCS7 *token)
270{
271 TS_TST_INFO *tst_info = PKCS7_to_TS_TST_INFO(token);
272 int ret = 0;
273 if (tst_info) {
274 ret = int_ts_RESP_verify_token(ctx, token, tst_info);
275 TS_TST_INFO_free(tst_info);
276 }
277 return ret;
278}
279
280/*-
281 * Verifies whether the 'token' contains a valid time stamp token
282 * with regards to the settings of the context. Only those checks are
283 * carried out that are specified in the context:
284 * - Verifies the signature of the TS_TST_INFO.
285 * - Checks the version number of the response.
286 * - Check if the requested and returned policies math.
287 * - Check if the message imprints are the same.
288 * - Check if the nonces are the same.
289 * - Check if the TSA name matches the signer.
290 * - Check if the TSA name is the expected TSA.
291 */
292static int int_ts_RESP_verify_token(TS_VERIFY_CTX *ctx,
293 PKCS7 *token, TS_TST_INFO *tst_info)
294{
295 X509 *signer = NULL((void*)0);
296 GENERAL_NAME *tsa_name = tst_info->tsa;
297 X509_ALGOR *md_alg = NULL((void*)0);
298 unsigned char *imprint = NULL((void*)0);
299 unsigned imprint_len = 0;
300 int ret = 0;
301 int flags = ctx->flags;
302
303 /* Some options require us to also check the signature */
304 if (((flags & TS_VFY_SIGNER(1u << 6)) && tsa_name != NULL((void*)0))
305 || (flags & TS_VFY_TSA_NAME(1u << 7))) {
306 flags |= TS_VFY_SIGNATURE(1u << 0);
307 }
308
309 if ((flags & TS_VFY_SIGNATURE(1u << 0))
310 && !TS_RESP_verify_signature(token, ctx->certs, ctx->store, &signer))
311 goto err;
312 if ((flags & TS_VFY_VERSION(1u << 1))
313 && TS_TST_INFO_get_version(tst_info) != 1) {
314 ERR_raise(ERR_LIB_TS, TS_R_UNSUPPORTED_VERSION)(ERR_new(), ERR_set_debug("../deps/openssl/openssl/crypto/ts/ts_rsp_verify.c"
,314,__func__), ERR_set_error)((47),(113),((void*)0))
;
315 goto err;
316 }
317 if ((flags & TS_VFY_POLICY(1u << 2))
318 && !ts_check_policy(ctx->policy, tst_info))
319 goto err;
320 if ((flags & TS_VFY_IMPRINT(1u << 3))
321 && !ts_check_imprints(ctx->md_alg, ctx->imprint, ctx->imprint_len,
322 tst_info))
323 goto err;
324 if ((flags & TS_VFY_DATA(1u << 4))
325 && (!ts_compute_imprint(ctx->data, tst_info,
326 &md_alg, &imprint, &imprint_len)
327 || !ts_check_imprints(md_alg, imprint, imprint_len, tst_info)))
328 goto err;
329 if ((flags & TS_VFY_NONCE(1u << 5))
330 && !ts_check_nonces(ctx->nonce, tst_info))
331 goto err;
332 if ((flags & TS_VFY_SIGNER(1u << 6))
333 && tsa_name && !ts_check_signer_name(tsa_name, signer)) {
334 ERR_raise(ERR_LIB_TS, TS_R_TSA_NAME_MISMATCH)(ERR_new(), ERR_set_debug("../deps/openssl/openssl/crypto/ts/ts_rsp_verify.c"
,334,__func__), ERR_set_error)((47),(111),((void*)0))
;
335 goto err;
336 }
337 if ((flags & TS_VFY_TSA_NAME(1u << 7))
338 && !ts_check_signer_name(ctx->tsa_name, signer)) {
339 ERR_raise(ERR_LIB_TS, TS_R_TSA_UNTRUSTED)(ERR_new(), ERR_set_debug("../deps/openssl/openssl/crypto/ts/ts_rsp_verify.c"
,339,__func__), ERR_set_error)((47),(112),((void*)0))
;
340 goto err;
341 }
342 ret = 1;
343
344 err:
345 X509_free(signer);
346 X509_ALGOR_free(md_alg);
347 OPENSSL_free(imprint)CRYPTO_free(imprint, "../deps/openssl/openssl/crypto/ts/ts_rsp_verify.c"
, 347)
;
348 return ret;
349}
350
351static int ts_check_status_info(TS_RESP *response)
352{
353 TS_STATUS_INFO *info = response->status_info;
354 long status = ASN1_INTEGER_get(info->status);
355 const char *status_text = NULL((void*)0);
356 char *embedded_status_text = NULL((void*)0);
357 char failure_text[TS_STATUS_BUF_SIZE256] = "";
358
359 if (status == 0 || status == 1)
360 return 1;
361
362 /* There was an error, get the description in status_text. */
363 if (0 <= status && status < (long) OSSL_NELEM(ts_status_text)(sizeof(ts_status_text)/sizeof((ts_status_text)[0])))
364 status_text = ts_status_text[status];
365 else
366 status_text = "unknown code";
367
368 if (sk_ASN1_UTF8STRING_num(info->text)OPENSSL_sk_num(ossl_check_const_ASN1_UTF8STRING_sk_type(info->
text))
> 0
369 && (embedded_status_text = ts_get_status_text(info->text)) == NULL((void*)0))
370 return 0;
371
372 /* Fill in failure_text with the failure information. */
373 if (info->failure_info) {
374 int i;
375 int first = 1;
376 for (i = 0; i < (int)OSSL_NELEM(ts_failure_info)(sizeof(ts_failure_info)/sizeof((ts_failure_info)[0])); ++i) {
377 if (ASN1_BIT_STRING_get_bit(info->failure_info,
378 ts_failure_info[i].code)) {
379 if (!first)
380 strcat(failure_text, ",");
381 else
382 first = 0;
383 strcat(failure_text, ts_failure_info[i].text);
384 }
385 }
386 }
387 if (failure_text[0] == '\0')
388 strcpy(failure_text, "unspecified");
389
390 ERR_raise_data(ERR_new(), ERR_set_debug("../deps/openssl/openssl/crypto/ts/ts_rsp_verify.c"
,390,__func__), ERR_set_error)
(ERR_LIB_TS47, TS_R_NO_TIME_STAMP_TOKEN107,
391 "status code: %s, status text: %s, failure codes: %s",
392 status_text,
393 embedded_status_text ? embedded_status_text : "unspecified",
394 failure_text);
395 OPENSSL_free(embedded_status_text)CRYPTO_free(embedded_status_text, "../deps/openssl/openssl/crypto/ts/ts_rsp_verify.c"
, 395)
;
396
397 return 0;
398}
399
400static char *ts_get_status_text(STACK_OF(ASN1_UTF8STRING)struct stack_st_ASN1_UTF8STRING *text)
401{
402 return ossl_sk_ASN1_UTF8STRING2text(text, "/", TS_MAX_STATUS_LENGTH(1024 * 1024));
403}
404
405static int ts_check_policy(const ASN1_OBJECT *req_oid,
406 const TS_TST_INFO *tst_info)
407{
408 const ASN1_OBJECT *resp_oid = tst_info->policy_id;
409
410 if (OBJ_cmp(req_oid, resp_oid) != 0) {
411 ERR_raise(ERR_LIB_TS, TS_R_POLICY_MISMATCH)(ERR_new(), ERR_set_debug("../deps/openssl/openssl/crypto/ts/ts_rsp_verify.c"
,411,__func__), ERR_set_error)((47),(108),((void*)0))
;
412 return 0;
413 }
414
415 return 1;
416}
417
418static int ts_compute_imprint(BIO *data, TS_TST_INFO *tst_info,
419 X509_ALGOR **md_alg,
420 unsigned char **imprint, unsigned *imprint_len)
421{
422 TS_MSG_IMPRINT *msg_imprint = tst_info->msg_imprint;
423 X509_ALGOR *md_alg_resp = msg_imprint->hash_algo;
424 EVP_MD *md = NULL((void*)0);
425 EVP_MD_CTX *md_ctx = NULL((void*)0);
426 unsigned char buffer[4096];
427 char name[OSSL_MAX_NAME_SIZE50];
428 int length;
429
430 *md_alg = NULL((void*)0);
431 *imprint = NULL((void*)0);
432
433 if ((*md_alg = X509_ALGOR_dup(md_alg_resp)) == NULL((void*)0))
434 goto err;
435
436 OBJ_obj2txt(name, sizeof(name), md_alg_resp->algorithm, 0);
437
438 (void)ERR_set_mark();
439 md = EVP_MD_fetch(NULL((void*)0), name, NULL((void*)0));
440
441 if (md == NULL((void*)0))
442 md = (EVP_MD *)EVP_get_digestbyname(name);
443
444 if (md == NULL((void*)0)) {
445 (void)ERR_clear_last_mark();
446 goto err;
447 }
448 (void)ERR_pop_to_mark();
449
450 length = EVP_MD_get_size(md);
451 if (length < 0)
452 goto err;
453 *imprint_len = length;
454 if ((*imprint = OPENSSL_malloc(*imprint_len)CRYPTO_malloc(*imprint_len, "../deps/openssl/openssl/crypto/ts/ts_rsp_verify.c"
, 454)
) == NULL((void*)0)) {
455 ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE)(ERR_new(), ERR_set_debug("../deps/openssl/openssl/crypto/ts/ts_rsp_verify.c"
,455,__func__), ERR_set_error)((47),((256|((0x1 << 18L)
|(0x2 << 18L)))),((void*)0))
;
456 goto err;
457 }
458
459 md_ctx = EVP_MD_CTX_new();
460 if (md_ctx == NULL((void*)0)) {
461 ERR_raise(ERR_LIB_TS, ERR_R_MALLOC_FAILURE)(ERR_new(), ERR_set_debug("../deps/openssl/openssl/crypto/ts/ts_rsp_verify.c"
,461,__func__), ERR_set_error)((47),((256|((0x1 << 18L)
|(0x2 << 18L)))),((void*)0))
;
462 goto err;
463 }
464 if (!EVP_DigestInit(md_ctx, md))
465 goto err;
466 EVP_MD_free(md);
467 md = NULL((void*)0);
468 while ((length = BIO_read(data, buffer, sizeof(buffer))) > 0) {
469 if (!EVP_DigestUpdate(md_ctx, buffer, length))
470 goto err;
471 }
472 if (!EVP_DigestFinal(md_ctx, *imprint, NULL((void*)0)))
473 goto err;
474 EVP_MD_CTX_free(md_ctx);
475
476 return 1;
477 err:
478 EVP_MD_CTX_free(md_ctx);
479 EVP_MD_free(md);
480 X509_ALGOR_free(*md_alg);
481 *md_alg = NULL((void*)0);
482 OPENSSL_free(*imprint)CRYPTO_free(*imprint, "../deps/openssl/openssl/crypto/ts/ts_rsp_verify.c"
, 482)
;
483 *imprint_len = 0;
484 *imprint = 0;
485 return 0;
486}
487
488static int ts_check_imprints(X509_ALGOR *algor_a,
489 const unsigned char *imprint_a, unsigned len_a,
490 TS_TST_INFO *tst_info)
491{
492 TS_MSG_IMPRINT *b = tst_info->msg_imprint;
493 X509_ALGOR *algor_b = b->hash_algo;
494 int ret = 0;
495
496 if (algor_a) {
497 if (OBJ_cmp(algor_a->algorithm, algor_b->algorithm))
498 goto err;
499
500 /* The parameter must be NULL in both. */
501 if ((algor_a->parameter
502 && ASN1_TYPE_get(algor_a->parameter) != V_ASN1_NULL5)
503 || (algor_b->parameter
504 && ASN1_TYPE_get(algor_b->parameter) != V_ASN1_NULL5))
505 goto err;
506 }
507
508 ret = len_a == (unsigned)ASN1_STRING_length(b->hashed_msg) &&
509 memcmp(imprint_a, ASN1_STRING_get0_data(b->hashed_msg), len_a) == 0;
510 err:
511 if (!ret)
512 ERR_raise(ERR_LIB_TS, TS_R_MESSAGE_IMPRINT_MISMATCH)(ERR_new(), ERR_set_debug("../deps/openssl/openssl/crypto/ts/ts_rsp_verify.c"
,512,__func__), ERR_set_error)((47),(103),((void*)0))
;
513 return ret;
514}
515
516static int ts_check_nonces(const ASN1_INTEGER *a, TS_TST_INFO *tst_info)
517{
518 const ASN1_INTEGER *b = tst_info->nonce;
519
520 if (!b) {
521 ERR_raise(ERR_LIB_TS, TS_R_NONCE_NOT_RETURNED)(ERR_new(), ERR_set_debug("../deps/openssl/openssl/crypto/ts/ts_rsp_verify.c"
,521,__func__), ERR_set_error)((47),(105),((void*)0))
;
522 return 0;
523 }
524
525 /* No error if a nonce is returned without being requested. */
526 if (ASN1_INTEGER_cmp(a, b) != 0) {
527 ERR_raise(ERR_LIB_TS, TS_R_NONCE_MISMATCH)(ERR_new(), ERR_set_debug("../deps/openssl/openssl/crypto/ts/ts_rsp_verify.c"
,527,__func__), ERR_set_error)((47),(104),((void*)0))
;
528 return 0;
529 }
530
531 return 1;
532}
533
534/*
535 * Check if the specified TSA name matches either the subject or one of the
536 * subject alternative names of the TSA certificate.
537 */
538static int ts_check_signer_name(GENERAL_NAME *tsa_name, X509 *signer)
539{
540 STACK_OF(GENERAL_NAME)struct stack_st_GENERAL_NAME *gen_names = NULL((void*)0);
541 int idx = -1;
542 int found = 0;
543
544 if (tsa_name->type == GEN_DIRNAME4
545 && X509_name_cmp(tsa_name->d.dirn, X509_get_subject_name(signer))X509_NAME_cmp((tsa_name->d.dirn),(X509_get_subject_name(signer
)))
== 0)
546 return 1;
547 gen_names = X509_get_ext_d2i(signer, NID_subject_alt_name85, NULL((void*)0), &idx);
548 while (gen_names != NULL((void*)0)) {
549 found = ts_find_name(gen_names, tsa_name) >= 0;
550 if (found)
551 break;
552 /*
553 * Get the next subject alternative name, although there should be no
554 * more than one.
555 */
556 GENERAL_NAMES_free(gen_names);
557 gen_names = X509_get_ext_d2i(signer, NID_subject_alt_name85, NULL((void*)0), &idx);
558 }
559 GENERAL_NAMES_free(gen_names);
560
561 return found;
562}
563
564/* Returns 1 if name is in gen_names, 0 otherwise. */
565static int ts_find_name(STACK_OF(GENERAL_NAME)struct stack_st_GENERAL_NAME *gen_names, GENERAL_NAME *name)
566{
567 int i, found;
568 for (i = 0, found = 0; !found && i < sk_GENERAL_NAME_num(gen_names)OPENSSL_sk_num(ossl_check_const_GENERAL_NAME_sk_type(gen_names
))
; ++i) {
569 GENERAL_NAME *current = sk_GENERAL_NAME_value(gen_names, i)((GENERAL_NAME *)OPENSSL_sk_value(ossl_check_const_GENERAL_NAME_sk_type
(gen_names), (i)))
;
570 found = GENERAL_NAME_cmp(current, name) == 0;
571 }
572 return found ? i - 1 : -1;
573}