Absolute File Name: | /home/opencoverage/opencoverage/guest-scripts/openssl/src/crypto/ts/ts_rsp_sign.c |
Source code | Switch to Preprocessed file |
Line | Source | Count | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | /* | - | ||||||||||||||||||
2 | * Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved. | - | ||||||||||||||||||
3 | * | - | ||||||||||||||||||
4 | * Licensed under the OpenSSL license (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 "e_os.h" | - | ||||||||||||||||||
11 | #include "internal/cryptlib.h" | - | ||||||||||||||||||
12 | - | |||||||||||||||||||
13 | #include <openssl/objects.h> | - | ||||||||||||||||||
14 | #include <openssl/ts.h> | - | ||||||||||||||||||
15 | #include <openssl/pkcs7.h> | - | ||||||||||||||||||
16 | #include <openssl/crypto.h> | - | ||||||||||||||||||
17 | #include "ts_lcl.h" | - | ||||||||||||||||||
18 | - | |||||||||||||||||||
19 | static ASN1_INTEGER *def_serial_cb(struct TS_resp_ctx *, void *); | - | ||||||||||||||||||
20 | static int def_time_cb(struct TS_resp_ctx *, void *, long *sec, long *usec); | - | ||||||||||||||||||
21 | static int def_extension_cb(struct TS_resp_ctx *, X509_EXTENSION *, void *); | - | ||||||||||||||||||
22 | - | |||||||||||||||||||
23 | static void ts_RESP_CTX_init(TS_RESP_CTX *ctx); | - | ||||||||||||||||||
24 | static void ts_RESP_CTX_cleanup(TS_RESP_CTX *ctx); | - | ||||||||||||||||||
25 | static int ts_RESP_check_request(TS_RESP_CTX *ctx); | - | ||||||||||||||||||
26 | static ASN1_OBJECT *ts_RESP_get_policy(TS_RESP_CTX *ctx); | - | ||||||||||||||||||
27 | static TS_TST_INFO *ts_RESP_create_tst_info(TS_RESP_CTX *ctx, | - | ||||||||||||||||||
28 | ASN1_OBJECT *policy); | - | ||||||||||||||||||
29 | static int ts_RESP_process_extensions(TS_RESP_CTX *ctx); | - | ||||||||||||||||||
30 | static int ts_RESP_sign(TS_RESP_CTX *ctx); | - | ||||||||||||||||||
31 | - | |||||||||||||||||||
32 | static ESS_SIGNING_CERT *ess_SIGNING_CERT_new_init(X509 *signcert, | - | ||||||||||||||||||
33 | STACK_OF(X509) *certs); | - | ||||||||||||||||||
34 | static ESS_CERT_ID *ess_CERT_ID_new_init(X509 *cert, int issuer_needed); | - | ||||||||||||||||||
35 | static int ts_TST_INFO_content_new(PKCS7 *p7); | - | ||||||||||||||||||
36 | static int ess_add_signing_cert(PKCS7_SIGNER_INFO *si, ESS_SIGNING_CERT *sc); | - | ||||||||||||||||||
37 | - | |||||||||||||||||||
38 | static ESS_SIGNING_CERT_V2 *ess_signing_cert_v2_new_init(const EVP_MD *hash_alg, | - | ||||||||||||||||||
39 | X509 *signcert, | - | ||||||||||||||||||
40 | STACK_OF(X509) | - | ||||||||||||||||||
41 | *certs); | - | ||||||||||||||||||
42 | static ESS_CERT_ID_V2 *ess_cert_id_v2_new_init(const EVP_MD *hash_alg, | - | ||||||||||||||||||
43 | X509 *cert, int issuer_needed); | - | ||||||||||||||||||
44 | static int ess_add_signing_cert_v2(PKCS7_SIGNER_INFO *si, | - | ||||||||||||||||||
45 | ESS_SIGNING_CERT_V2 *sc); | - | ||||||||||||||||||
46 | - | |||||||||||||||||||
47 | static ASN1_GENERALIZEDTIME | - | ||||||||||||||||||
48 | *TS_RESP_set_genTime_with_precision(ASN1_GENERALIZEDTIME *, long, long, | - | ||||||||||||||||||
49 | unsigned); | - | ||||||||||||||||||
50 | - | |||||||||||||||||||
51 | /* Default callback for response generation. */ | - | ||||||||||||||||||
52 | static ASN1_INTEGER *def_serial_cb(struct TS_resp_ctx *ctx, void *data) | - | ||||||||||||||||||
53 | { | - | ||||||||||||||||||
54 | ASN1_INTEGER *serial = ASN1_INTEGER_new(); | - | ||||||||||||||||||
55 | - | |||||||||||||||||||
56 | if (serial == NULL)
| 0 | ||||||||||||||||||
57 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
58 | if (!ASN1_INTEGER_set(serial, 1))
| 0 | ||||||||||||||||||
59 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
60 | return serial; never executed: return serial; | 0 | ||||||||||||||||||
61 | - | |||||||||||||||||||
62 | err: | - | ||||||||||||||||||
63 | TSerr(TS_F_DEF_SERIAL_CB, ERR_R_MALLOC_FAILURE); | - | ||||||||||||||||||
64 | TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, | - | ||||||||||||||||||
65 | "Error during serial number generation."); | - | ||||||||||||||||||
66 | return NULL; never executed: return ((void *)0) ; | 0 | ||||||||||||||||||
67 | } | - | ||||||||||||||||||
68 | - | |||||||||||||||||||
69 | #if defined(OPENSSL_SYS_UNIX) | - | ||||||||||||||||||
70 | - | |||||||||||||||||||
71 | static int def_time_cb(struct TS_resp_ctx *ctx, void *data, | - | ||||||||||||||||||
72 | long *sec, long *usec) | - | ||||||||||||||||||
73 | { | - | ||||||||||||||||||
74 | struct timeval tv; | - | ||||||||||||||||||
75 | if (gettimeofday(&tv, NULL) != 0) {
| 0 | ||||||||||||||||||
76 | TSerr(TS_F_DEF_TIME_CB, TS_R_TIME_SYSCALL_ERROR); | - | ||||||||||||||||||
77 | TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, | - | ||||||||||||||||||
78 | "Time is not available."); | - | ||||||||||||||||||
79 | TS_RESP_CTX_add_failure_info(ctx, TS_INFO_TIME_NOT_AVAILABLE); | - | ||||||||||||||||||
80 | return 0; never executed: return 0; | 0 | ||||||||||||||||||
81 | } | - | ||||||||||||||||||
82 | *sec = tv.tv_sec; | - | ||||||||||||||||||
83 | *usec = tv.tv_usec; | - | ||||||||||||||||||
84 | - | |||||||||||||||||||
85 | return 1; never executed: return 1; | 0 | ||||||||||||||||||
86 | } | - | ||||||||||||||||||
87 | - | |||||||||||||||||||
88 | #else | - | ||||||||||||||||||
89 | - | |||||||||||||||||||
90 | static int def_time_cb(struct TS_resp_ctx *ctx, void *data, | - | ||||||||||||||||||
91 | long *sec, long *usec) | - | ||||||||||||||||||
92 | { | - | ||||||||||||||||||
93 | time_t t; | - | ||||||||||||||||||
94 | if (time(&t) == (time_t)-1) { | - | ||||||||||||||||||
95 | TSerr(TS_F_DEF_TIME_CB, TS_R_TIME_SYSCALL_ERROR); | - | ||||||||||||||||||
96 | TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, | - | ||||||||||||||||||
97 | "Time is not available."); | - | ||||||||||||||||||
98 | TS_RESP_CTX_add_failure_info(ctx, TS_INFO_TIME_NOT_AVAILABLE); | - | ||||||||||||||||||
99 | return 0; | - | ||||||||||||||||||
100 | } | - | ||||||||||||||||||
101 | *sec = (long)t; | - | ||||||||||||||||||
102 | *usec = 0; | - | ||||||||||||||||||
103 | - | |||||||||||||||||||
104 | return 1; | - | ||||||||||||||||||
105 | } | - | ||||||||||||||||||
106 | - | |||||||||||||||||||
107 | #endif | - | ||||||||||||||||||
108 | - | |||||||||||||||||||
109 | static int def_extension_cb(struct TS_resp_ctx *ctx, X509_EXTENSION *ext, | - | ||||||||||||||||||
110 | void *data) | - | ||||||||||||||||||
111 | { | - | ||||||||||||||||||
112 | TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, | - | ||||||||||||||||||
113 | "Unsupported extension."); | - | ||||||||||||||||||
114 | TS_RESP_CTX_add_failure_info(ctx, TS_INFO_UNACCEPTED_EXTENSION); | - | ||||||||||||||||||
115 | return 0; never executed: return 0; | 0 | ||||||||||||||||||
116 | } | - | ||||||||||||||||||
117 | - | |||||||||||||||||||
118 | /* TS_RESP_CTX management functions. */ | - | ||||||||||||||||||
119 | - | |||||||||||||||||||
120 | TS_RESP_CTX *TS_RESP_CTX_new(void) | - | ||||||||||||||||||
121 | { | - | ||||||||||||||||||
122 | TS_RESP_CTX *ctx; | - | ||||||||||||||||||
123 | - | |||||||||||||||||||
124 | if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) {
| 0 | ||||||||||||||||||
125 | TSerr(TS_F_TS_RESP_CTX_NEW, ERR_R_MALLOC_FAILURE); | - | ||||||||||||||||||
126 | return NULL; never executed: return ((void *)0) ; | 0 | ||||||||||||||||||
127 | } | - | ||||||||||||||||||
128 | - | |||||||||||||||||||
129 | ctx->signer_md = EVP_sha256(); | - | ||||||||||||||||||
130 | - | |||||||||||||||||||
131 | ctx->serial_cb = def_serial_cb; | - | ||||||||||||||||||
132 | ctx->time_cb = def_time_cb; | - | ||||||||||||||||||
133 | ctx->extension_cb = def_extension_cb; | - | ||||||||||||||||||
134 | - | |||||||||||||||||||
135 | return ctx; never executed: return ctx; | 0 | ||||||||||||||||||
136 | } | - | ||||||||||||||||||
137 | - | |||||||||||||||||||
138 | void TS_RESP_CTX_free(TS_RESP_CTX *ctx) | - | ||||||||||||||||||
139 | { | - | ||||||||||||||||||
140 | if (!ctx)
| 0 | ||||||||||||||||||
141 | return; never executed: return; | 0 | ||||||||||||||||||
142 | - | |||||||||||||||||||
143 | X509_free(ctx->signer_cert); | - | ||||||||||||||||||
144 | EVP_PKEY_free(ctx->signer_key); | - | ||||||||||||||||||
145 | sk_X509_pop_free(ctx->certs, X509_free); | - | ||||||||||||||||||
146 | sk_ASN1_OBJECT_pop_free(ctx->policies, ASN1_OBJECT_free); | - | ||||||||||||||||||
147 | ASN1_OBJECT_free(ctx->default_policy); | - | ||||||||||||||||||
148 | sk_EVP_MD_free(ctx->mds); /* No EVP_MD_free method exists. */ | - | ||||||||||||||||||
149 | ASN1_INTEGER_free(ctx->seconds); | - | ||||||||||||||||||
150 | ASN1_INTEGER_free(ctx->millis); | - | ||||||||||||||||||
151 | ASN1_INTEGER_free(ctx->micros); | - | ||||||||||||||||||
152 | OPENSSL_free(ctx); | - | ||||||||||||||||||
153 | } never executed: end of block | 0 | ||||||||||||||||||
154 | - | |||||||||||||||||||
155 | int TS_RESP_CTX_set_signer_cert(TS_RESP_CTX *ctx, X509 *signer) | - | ||||||||||||||||||
156 | { | - | ||||||||||||||||||
157 | if (X509_check_purpose(signer, X509_PURPOSE_TIMESTAMP_SIGN, 0) != 1) {
| 0 | ||||||||||||||||||
158 | TSerr(TS_F_TS_RESP_CTX_SET_SIGNER_CERT, | - | ||||||||||||||||||
159 | TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE); | - | ||||||||||||||||||
160 | return 0; never executed: return 0; | 0 | ||||||||||||||||||
161 | } | - | ||||||||||||||||||
162 | X509_free(ctx->signer_cert); | - | ||||||||||||||||||
163 | ctx->signer_cert = signer; | - | ||||||||||||||||||
164 | X509_up_ref(ctx->signer_cert); | - | ||||||||||||||||||
165 | return 1; never executed: return 1; | 0 | ||||||||||||||||||
166 | } | - | ||||||||||||||||||
167 | - | |||||||||||||||||||
168 | int TS_RESP_CTX_set_signer_key(TS_RESP_CTX *ctx, EVP_PKEY *key) | - | ||||||||||||||||||
169 | { | - | ||||||||||||||||||
170 | EVP_PKEY_free(ctx->signer_key); | - | ||||||||||||||||||
171 | ctx->signer_key = key; | - | ||||||||||||||||||
172 | EVP_PKEY_up_ref(ctx->signer_key); | - | ||||||||||||||||||
173 | - | |||||||||||||||||||
174 | return 1; never executed: return 1; | 0 | ||||||||||||||||||
175 | } | - | ||||||||||||||||||
176 | - | |||||||||||||||||||
177 | int TS_RESP_CTX_set_signer_digest(TS_RESP_CTX *ctx, const EVP_MD *md) | - | ||||||||||||||||||
178 | { | - | ||||||||||||||||||
179 | ctx->signer_md = md; | - | ||||||||||||||||||
180 | return 1; never executed: return 1; | 0 | ||||||||||||||||||
181 | } | - | ||||||||||||||||||
182 | - | |||||||||||||||||||
183 | int TS_RESP_CTX_set_def_policy(TS_RESP_CTX *ctx, const ASN1_OBJECT *def_policy) | - | ||||||||||||||||||
184 | { | - | ||||||||||||||||||
185 | ASN1_OBJECT_free(ctx->default_policy); | - | ||||||||||||||||||
186 | if ((ctx->default_policy = OBJ_dup(def_policy)) == NULL)
| 0 | ||||||||||||||||||
187 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
188 | return 1; never executed: return 1; | 0 | ||||||||||||||||||
189 | err: | - | ||||||||||||||||||
190 | TSerr(TS_F_TS_RESP_CTX_SET_DEF_POLICY, ERR_R_MALLOC_FAILURE); | - | ||||||||||||||||||
191 | return 0; never executed: return 0; | 0 | ||||||||||||||||||
192 | } | - | ||||||||||||||||||
193 | - | |||||||||||||||||||
194 | int TS_RESP_CTX_set_certs(TS_RESP_CTX *ctx, STACK_OF(X509) *certs) | - | ||||||||||||||||||
195 | { | - | ||||||||||||||||||
196 | - | |||||||||||||||||||
197 | sk_X509_pop_free(ctx->certs, X509_free); | - | ||||||||||||||||||
198 | ctx->certs = NULL; | - | ||||||||||||||||||
199 | if (!certs)
| 0 | ||||||||||||||||||
200 | return 1; never executed: return 1; | 0 | ||||||||||||||||||
201 | if ((ctx->certs = X509_chain_up_ref(certs)) == NULL) {
| 0 | ||||||||||||||||||
202 | TSerr(TS_F_TS_RESP_CTX_SET_CERTS, ERR_R_MALLOC_FAILURE); | - | ||||||||||||||||||
203 | return 0; never executed: return 0; | 0 | ||||||||||||||||||
204 | } | - | ||||||||||||||||||
205 | - | |||||||||||||||||||
206 | return 1; never executed: return 1; | 0 | ||||||||||||||||||
207 | } | - | ||||||||||||||||||
208 | - | |||||||||||||||||||
209 | int TS_RESP_CTX_add_policy(TS_RESP_CTX *ctx, const ASN1_OBJECT *policy) | - | ||||||||||||||||||
210 | { | - | ||||||||||||||||||
211 | ASN1_OBJECT *copy = NULL; | - | ||||||||||||||||||
212 | - | |||||||||||||||||||
213 | if (ctx->policies == NULL
| 0 | ||||||||||||||||||
214 | && (ctx->policies = sk_ASN1_OBJECT_new_null()) == NULL)
| 0 | ||||||||||||||||||
215 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
216 | if ((copy = OBJ_dup(policy)) == NULL)
| 0 | ||||||||||||||||||
217 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
218 | if (!sk_ASN1_OBJECT_push(ctx->policies, copy))
| 0 | ||||||||||||||||||
219 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
220 | - | |||||||||||||||||||
221 | return 1; never executed: return 1; | 0 | ||||||||||||||||||
222 | err: | - | ||||||||||||||||||
223 | TSerr(TS_F_TS_RESP_CTX_ADD_POLICY, ERR_R_MALLOC_FAILURE); | - | ||||||||||||||||||
224 | ASN1_OBJECT_free(copy); | - | ||||||||||||||||||
225 | return 0; never executed: return 0; | 0 | ||||||||||||||||||
226 | } | - | ||||||||||||||||||
227 | - | |||||||||||||||||||
228 | int TS_RESP_CTX_add_md(TS_RESP_CTX *ctx, const EVP_MD *md) | - | ||||||||||||||||||
229 | { | - | ||||||||||||||||||
230 | if (ctx->mds == NULL
| 0 | ||||||||||||||||||
231 | && (ctx->mds = sk_EVP_MD_new_null()) == NULL)
| 0 | ||||||||||||||||||
232 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
233 | if (!sk_EVP_MD_push(ctx->mds, md))
| 0 | ||||||||||||||||||
234 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
235 | - | |||||||||||||||||||
236 | return 1; never executed: return 1; | 0 | ||||||||||||||||||
237 | err: | - | ||||||||||||||||||
238 | TSerr(TS_F_TS_RESP_CTX_ADD_MD, ERR_R_MALLOC_FAILURE); | - | ||||||||||||||||||
239 | return 0; never executed: return 0; | 0 | ||||||||||||||||||
240 | } | - | ||||||||||||||||||
241 | - | |||||||||||||||||||
242 | #define TS_RESP_CTX_accuracy_free(ctx) \ | - | ||||||||||||||||||
243 | ASN1_INTEGER_free(ctx->seconds); \ | - | ||||||||||||||||||
244 | ctx->seconds = NULL; \ | - | ||||||||||||||||||
245 | ASN1_INTEGER_free(ctx->millis); \ | - | ||||||||||||||||||
246 | ctx->millis = NULL; \ | - | ||||||||||||||||||
247 | ASN1_INTEGER_free(ctx->micros); \ | - | ||||||||||||||||||
248 | ctx->micros = NULL; | - | ||||||||||||||||||
249 | - | |||||||||||||||||||
250 | int TS_RESP_CTX_set_accuracy(TS_RESP_CTX *ctx, | - | ||||||||||||||||||
251 | int secs, int millis, int micros) | - | ||||||||||||||||||
252 | { | - | ||||||||||||||||||
253 | - | |||||||||||||||||||
254 | TS_RESP_CTX_accuracy_free(ctx); | - | ||||||||||||||||||
255 | if (secs
| 0 | ||||||||||||||||||
256 | && ((ctx->seconds = ASN1_INTEGER_new()) == NULL
| 0 | ||||||||||||||||||
257 | || !ASN1_INTEGER_set(ctx->seconds, secs)))
| 0 | ||||||||||||||||||
258 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
259 | if (millis
| 0 | ||||||||||||||||||
260 | && ((ctx->millis = ASN1_INTEGER_new()) == NULL
| 0 | ||||||||||||||||||
261 | || !ASN1_INTEGER_set(ctx->millis, millis)))
| 0 | ||||||||||||||||||
262 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
263 | if (micros
| 0 | ||||||||||||||||||
264 | && ((ctx->micros = ASN1_INTEGER_new()) == NULL
| 0 | ||||||||||||||||||
265 | || !ASN1_INTEGER_set(ctx->micros, micros)))
| 0 | ||||||||||||||||||
266 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
267 | - | |||||||||||||||||||
268 | return 1; never executed: return 1; | 0 | ||||||||||||||||||
269 | err: | - | ||||||||||||||||||
270 | TS_RESP_CTX_accuracy_free(ctx); | - | ||||||||||||||||||
271 | TSerr(TS_F_TS_RESP_CTX_SET_ACCURACY, ERR_R_MALLOC_FAILURE); | - | ||||||||||||||||||
272 | return 0; never executed: return 0; | 0 | ||||||||||||||||||
273 | } | - | ||||||||||||||||||
274 | - | |||||||||||||||||||
275 | void TS_RESP_CTX_add_flags(TS_RESP_CTX *ctx, int flags) | - | ||||||||||||||||||
276 | { | - | ||||||||||||||||||
277 | ctx->flags |= flags; | - | ||||||||||||||||||
278 | } never executed: end of block | 0 | ||||||||||||||||||
279 | - | |||||||||||||||||||
280 | void TS_RESP_CTX_set_serial_cb(TS_RESP_CTX *ctx, TS_serial_cb cb, void *data) | - | ||||||||||||||||||
281 | { | - | ||||||||||||||||||
282 | ctx->serial_cb = cb; | - | ||||||||||||||||||
283 | ctx->serial_cb_data = data; | - | ||||||||||||||||||
284 | } never executed: end of block | 0 | ||||||||||||||||||
285 | - | |||||||||||||||||||
286 | void TS_RESP_CTX_set_time_cb(TS_RESP_CTX *ctx, TS_time_cb cb, void *data) | - | ||||||||||||||||||
287 | { | - | ||||||||||||||||||
288 | ctx->time_cb = cb; | - | ||||||||||||||||||
289 | ctx->time_cb_data = data; | - | ||||||||||||||||||
290 | } never executed: end of block | 0 | ||||||||||||||||||
291 | - | |||||||||||||||||||
292 | void TS_RESP_CTX_set_extension_cb(TS_RESP_CTX *ctx, | - | ||||||||||||||||||
293 | TS_extension_cb cb, void *data) | - | ||||||||||||||||||
294 | { | - | ||||||||||||||||||
295 | ctx->extension_cb = cb; | - | ||||||||||||||||||
296 | ctx->extension_cb_data = data; | - | ||||||||||||||||||
297 | } never executed: end of block | 0 | ||||||||||||||||||
298 | - | |||||||||||||||||||
299 | int TS_RESP_CTX_set_status_info(TS_RESP_CTX *ctx, | - | ||||||||||||||||||
300 | int status, const char *text) | - | ||||||||||||||||||
301 | { | - | ||||||||||||||||||
302 | TS_STATUS_INFO *si = NULL; | - | ||||||||||||||||||
303 | ASN1_UTF8STRING *utf8_text = NULL; | - | ||||||||||||||||||
304 | int ret = 0; | - | ||||||||||||||||||
305 | - | |||||||||||||||||||
306 | if ((si = TS_STATUS_INFO_new()) == NULL)
| 0 | ||||||||||||||||||
307 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
308 | if (!ASN1_INTEGER_set(si->status, status))
| 0 | ||||||||||||||||||
309 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
310 | if (text) {
| 0 | ||||||||||||||||||
311 | if ((utf8_text = ASN1_UTF8STRING_new()) == NULL
| 0 | ||||||||||||||||||
312 | || !ASN1_STRING_set(utf8_text, text, strlen(text)))
| 0 | ||||||||||||||||||
313 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
314 | if (si->text == NULL
| 0 | ||||||||||||||||||
315 | && (si->text = sk_ASN1_UTF8STRING_new_null()) == NULL)
| 0 | ||||||||||||||||||
316 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
317 | if (!sk_ASN1_UTF8STRING_push(si->text, utf8_text))
| 0 | ||||||||||||||||||
318 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
319 | utf8_text = NULL; /* Ownership is lost. */ | - | ||||||||||||||||||
320 | } never executed: end of block | 0 | ||||||||||||||||||
321 | if (!TS_RESP_set_status_info(ctx->response, si))
| 0 | ||||||||||||||||||
322 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
323 | ret = 1; | - | ||||||||||||||||||
324 | err: code before this statement never executed: err: | 0 | ||||||||||||||||||
325 | if (!ret)
| 0 | ||||||||||||||||||
326 | TSerr(TS_F_TS_RESP_CTX_SET_STATUS_INFO, ERR_R_MALLOC_FAILURE); never executed: ERR_put_error(47,(132),((1|64)),__FILE__,326); | 0 | ||||||||||||||||||
327 | TS_STATUS_INFO_free(si); | - | ||||||||||||||||||
328 | ASN1_UTF8STRING_free(utf8_text); | - | ||||||||||||||||||
329 | return ret; never executed: return ret; | 0 | ||||||||||||||||||
330 | } | - | ||||||||||||||||||
331 | - | |||||||||||||||||||
332 | int TS_RESP_CTX_set_status_info_cond(TS_RESP_CTX *ctx, | - | ||||||||||||||||||
333 | int status, const char *text) | - | ||||||||||||||||||
334 | { | - | ||||||||||||||||||
335 | int ret = 1; | - | ||||||||||||||||||
336 | TS_STATUS_INFO *si = ctx->response->status_info; | - | ||||||||||||||||||
337 | - | |||||||||||||||||||
338 | if (ASN1_INTEGER_get(si->status) == TS_STATUS_GRANTED) {
| 0 | ||||||||||||||||||
339 | ret = TS_RESP_CTX_set_status_info(ctx, status, text); | - | ||||||||||||||||||
340 | } never executed: end of block | 0 | ||||||||||||||||||
341 | return ret; never executed: return ret; | 0 | ||||||||||||||||||
342 | } | - | ||||||||||||||||||
343 | - | |||||||||||||||||||
344 | int TS_RESP_CTX_add_failure_info(TS_RESP_CTX *ctx, int failure) | - | ||||||||||||||||||
345 | { | - | ||||||||||||||||||
346 | TS_STATUS_INFO *si = ctx->response->status_info; | - | ||||||||||||||||||
347 | if (si->failure_info == NULL
| 0 | ||||||||||||||||||
348 | && (si->failure_info = ASN1_BIT_STRING_new()) == NULL)
| 0 | ||||||||||||||||||
349 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
350 | if (!ASN1_BIT_STRING_set_bit(si->failure_info, failure, 1))
| 0 | ||||||||||||||||||
351 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
352 | return 1; never executed: return 1; | 0 | ||||||||||||||||||
353 | err: | - | ||||||||||||||||||
354 | TSerr(TS_F_TS_RESP_CTX_ADD_FAILURE_INFO, ERR_R_MALLOC_FAILURE); | - | ||||||||||||||||||
355 | return 0; never executed: return 0; | 0 | ||||||||||||||||||
356 | } | - | ||||||||||||||||||
357 | - | |||||||||||||||||||
358 | TS_REQ *TS_RESP_CTX_get_request(TS_RESP_CTX *ctx) | - | ||||||||||||||||||
359 | { | - | ||||||||||||||||||
360 | return ctx->request; never executed: return ctx->request; | 0 | ||||||||||||||||||
361 | } | - | ||||||||||||||||||
362 | - | |||||||||||||||||||
363 | TS_TST_INFO *TS_RESP_CTX_get_tst_info(TS_RESP_CTX *ctx) | - | ||||||||||||||||||
364 | { | - | ||||||||||||||||||
365 | return ctx->tst_info; never executed: return ctx->tst_info; | 0 | ||||||||||||||||||
366 | } | - | ||||||||||||||||||
367 | - | |||||||||||||||||||
368 | int TS_RESP_CTX_set_clock_precision_digits(TS_RESP_CTX *ctx, | - | ||||||||||||||||||
369 | unsigned precision) | - | ||||||||||||||||||
370 | { | - | ||||||||||||||||||
371 | if (precision > TS_MAX_CLOCK_PRECISION_DIGITS)
| 0 | ||||||||||||||||||
372 | return 0; never executed: return 0; | 0 | ||||||||||||||||||
373 | ctx->clock_precision_digits = precision; | - | ||||||||||||||||||
374 | return 1; never executed: return 1; | 0 | ||||||||||||||||||
375 | } | - | ||||||||||||||||||
376 | - | |||||||||||||||||||
377 | /* Main entry method of the response generation. */ | - | ||||||||||||||||||
378 | TS_RESP *TS_RESP_create_response(TS_RESP_CTX *ctx, BIO *req_bio) | - | ||||||||||||||||||
379 | { | - | ||||||||||||||||||
380 | ASN1_OBJECT *policy; | - | ||||||||||||||||||
381 | TS_RESP *response; | - | ||||||||||||||||||
382 | int result = 0; | - | ||||||||||||||||||
383 | - | |||||||||||||||||||
384 | ts_RESP_CTX_init(ctx); | - | ||||||||||||||||||
385 | - | |||||||||||||||||||
386 | if ((ctx->response = TS_RESP_new()) == NULL) {
| 0 | ||||||||||||||||||
387 | TSerr(TS_F_TS_RESP_CREATE_RESPONSE, ERR_R_MALLOC_FAILURE); | - | ||||||||||||||||||
388 | goto end; never executed: goto end; | 0 | ||||||||||||||||||
389 | } | - | ||||||||||||||||||
390 | if ((ctx->request = d2i_TS_REQ_bio(req_bio, NULL)) == NULL) {
| 0 | ||||||||||||||||||
391 | TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, | - | ||||||||||||||||||
392 | "Bad request format or system error."); | - | ||||||||||||||||||
393 | TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_DATA_FORMAT); | - | ||||||||||||||||||
394 | goto end; never executed: goto end; | 0 | ||||||||||||||||||
395 | } | - | ||||||||||||||||||
396 | if (!TS_RESP_CTX_set_status_info(ctx, TS_STATUS_GRANTED, NULL))
| 0 | ||||||||||||||||||
397 | goto end; never executed: goto end; | 0 | ||||||||||||||||||
398 | if (!ts_RESP_check_request(ctx))
| 0 | ||||||||||||||||||
399 | goto end; never executed: goto end; | 0 | ||||||||||||||||||
400 | if ((policy = ts_RESP_get_policy(ctx)) == NULL)
| 0 | ||||||||||||||||||
401 | goto end; never executed: goto end; | 0 | ||||||||||||||||||
402 | if ((ctx->tst_info = ts_RESP_create_tst_info(ctx, policy)) == NULL)
| 0 | ||||||||||||||||||
403 | goto end; never executed: goto end; | 0 | ||||||||||||||||||
404 | if (!ts_RESP_process_extensions(ctx))
| 0 | ||||||||||||||||||
405 | goto end; never executed: goto end; | 0 | ||||||||||||||||||
406 | if (!ts_RESP_sign(ctx))
| 0 | ||||||||||||||||||
407 | goto end; never executed: goto end; | 0 | ||||||||||||||||||
408 | result = 1; | - | ||||||||||||||||||
409 | - | |||||||||||||||||||
410 | end: code before this statement never executed: end: | 0 | ||||||||||||||||||
411 | if (!result) {
| 0 | ||||||||||||||||||
412 | TSerr(TS_F_TS_RESP_CREATE_RESPONSE, TS_R_RESPONSE_SETUP_ERROR); | - | ||||||||||||||||||
413 | if (ctx->response != NULL) {
| 0 | ||||||||||||||||||
414 | if (TS_RESP_CTX_set_status_info_cond(ctx,
| 0 | ||||||||||||||||||
415 | TS_STATUS_REJECTION,
| 0 | ||||||||||||||||||
416 | "Error during response "
| 0 | ||||||||||||||||||
417 | "generation.") == 0) {
| 0 | ||||||||||||||||||
418 | TS_RESP_free(ctx->response); | - | ||||||||||||||||||
419 | ctx->response = NULL; | - | ||||||||||||||||||
420 | } never executed: end of block | 0 | ||||||||||||||||||
421 | } never executed: end of block | 0 | ||||||||||||||||||
422 | } never executed: end of block | 0 | ||||||||||||||||||
423 | response = ctx->response; | - | ||||||||||||||||||
424 | ctx->response = NULL; /* Ownership will be returned to caller. */ | - | ||||||||||||||||||
425 | ts_RESP_CTX_cleanup(ctx); | - | ||||||||||||||||||
426 | return response; never executed: return response; | 0 | ||||||||||||||||||
427 | } | - | ||||||||||||||||||
428 | - | |||||||||||||||||||
429 | /* Initializes the variable part of the context. */ | - | ||||||||||||||||||
430 | static void ts_RESP_CTX_init(TS_RESP_CTX *ctx) | - | ||||||||||||||||||
431 | { | - | ||||||||||||||||||
432 | ctx->request = NULL; | - | ||||||||||||||||||
433 | ctx->response = NULL; | - | ||||||||||||||||||
434 | ctx->tst_info = NULL; | - | ||||||||||||||||||
435 | } never executed: end of block | 0 | ||||||||||||||||||
436 | - | |||||||||||||||||||
437 | /* Cleans up the variable part of the context. */ | - | ||||||||||||||||||
438 | static void ts_RESP_CTX_cleanup(TS_RESP_CTX *ctx) | - | ||||||||||||||||||
439 | { | - | ||||||||||||||||||
440 | TS_REQ_free(ctx->request); | - | ||||||||||||||||||
441 | ctx->request = NULL; | - | ||||||||||||||||||
442 | TS_RESP_free(ctx->response); | - | ||||||||||||||||||
443 | ctx->response = NULL; | - | ||||||||||||||||||
444 | TS_TST_INFO_free(ctx->tst_info); | - | ||||||||||||||||||
445 | ctx->tst_info = NULL; | - | ||||||||||||||||||
446 | } never executed: end of block | 0 | ||||||||||||||||||
447 | - | |||||||||||||||||||
448 | /* Checks the format and content of the request. */ | - | ||||||||||||||||||
449 | static int ts_RESP_check_request(TS_RESP_CTX *ctx) | - | ||||||||||||||||||
450 | { | - | ||||||||||||||||||
451 | TS_REQ *request = ctx->request; | - | ||||||||||||||||||
452 | TS_MSG_IMPRINT *msg_imprint; | - | ||||||||||||||||||
453 | X509_ALGOR *md_alg; | - | ||||||||||||||||||
454 | int md_alg_id; | - | ||||||||||||||||||
455 | const ASN1_OCTET_STRING *digest; | - | ||||||||||||||||||
456 | const EVP_MD *md = NULL; | - | ||||||||||||||||||
457 | int i; | - | ||||||||||||||||||
458 | - | |||||||||||||||||||
459 | if (TS_REQ_get_version(request) != 1) {
| 0 | ||||||||||||||||||
460 | TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, | - | ||||||||||||||||||
461 | "Bad request version."); | - | ||||||||||||||||||
462 | TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_REQUEST); | - | ||||||||||||||||||
463 | return 0; never executed: return 0; | 0 | ||||||||||||||||||
464 | } | - | ||||||||||||||||||
465 | - | |||||||||||||||||||
466 | msg_imprint = request->msg_imprint; | - | ||||||||||||||||||
467 | md_alg = msg_imprint->hash_algo; | - | ||||||||||||||||||
468 | md_alg_id = OBJ_obj2nid(md_alg->algorithm); | - | ||||||||||||||||||
469 | for (i = 0; !md && i < sk_EVP_MD_num(ctx->mds); ++i) {
| 0 | ||||||||||||||||||
470 | const EVP_MD *current_md = sk_EVP_MD_value(ctx->mds, i); | - | ||||||||||||||||||
471 | if (md_alg_id == EVP_MD_type(current_md))
| 0 | ||||||||||||||||||
472 | md = current_md; never executed: md = current_md; | 0 | ||||||||||||||||||
473 | } never executed: end of block | 0 | ||||||||||||||||||
474 | if (!md) {
| 0 | ||||||||||||||||||
475 | TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, | - | ||||||||||||||||||
476 | "Message digest algorithm is " | - | ||||||||||||||||||
477 | "not supported."); | - | ||||||||||||||||||
478 | TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_ALG); | - | ||||||||||||||||||
479 | return 0; never executed: return 0; | 0 | ||||||||||||||||||
480 | } | - | ||||||||||||||||||
481 | - | |||||||||||||||||||
482 | if (md_alg->parameter && ASN1_TYPE_get(md_alg->parameter) != V_ASN1_NULL) {
| 0 | ||||||||||||||||||
483 | TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, | - | ||||||||||||||||||
484 | "Superfluous message digest " | - | ||||||||||||||||||
485 | "parameter."); | - | ||||||||||||||||||
486 | TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_ALG); | - | ||||||||||||||||||
487 | return 0; never executed: return 0; | 0 | ||||||||||||||||||
488 | } | - | ||||||||||||||||||
489 | digest = msg_imprint->hashed_msg; | - | ||||||||||||||||||
490 | if (digest->length != EVP_MD_size(md)) {
| 0 | ||||||||||||||||||
491 | TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, | - | ||||||||||||||||||
492 | "Bad message digest."); | - | ||||||||||||||||||
493 | TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_DATA_FORMAT); | - | ||||||||||||||||||
494 | return 0; never executed: return 0; | 0 | ||||||||||||||||||
495 | } | - | ||||||||||||||||||
496 | - | |||||||||||||||||||
497 | return 1; never executed: return 1; | 0 | ||||||||||||||||||
498 | } | - | ||||||||||||||||||
499 | - | |||||||||||||||||||
500 | /* Returns the TSA policy based on the requested and acceptable policies. */ | - | ||||||||||||||||||
501 | static ASN1_OBJECT *ts_RESP_get_policy(TS_RESP_CTX *ctx) | - | ||||||||||||||||||
502 | { | - | ||||||||||||||||||
503 | ASN1_OBJECT *requested = ctx->request->policy_id; | - | ||||||||||||||||||
504 | ASN1_OBJECT *policy = NULL; | - | ||||||||||||||||||
505 | int i; | - | ||||||||||||||||||
506 | - | |||||||||||||||||||
507 | if (ctx->default_policy == NULL) {
| 0 | ||||||||||||||||||
508 | TSerr(TS_F_TS_RESP_GET_POLICY, TS_R_INVALID_NULL_POINTER); | - | ||||||||||||||||||
509 | return NULL; never executed: return ((void *)0) ; | 0 | ||||||||||||||||||
510 | } | - | ||||||||||||||||||
511 | if (!requested || !OBJ_cmp(requested, ctx->default_policy))
| 0 | ||||||||||||||||||
512 | policy = ctx->default_policy; never executed: policy = ctx->default_policy; | 0 | ||||||||||||||||||
513 | - | |||||||||||||||||||
514 | /* Check if the policy is acceptable. */ | - | ||||||||||||||||||
515 | for (i = 0; !policy && i < sk_ASN1_OBJECT_num(ctx->policies); ++i) {
| 0 | ||||||||||||||||||
516 | ASN1_OBJECT *current = sk_ASN1_OBJECT_value(ctx->policies, i); | - | ||||||||||||||||||
517 | if (!OBJ_cmp(requested, current))
| 0 | ||||||||||||||||||
518 | policy = current; never executed: policy = current; | 0 | ||||||||||||||||||
519 | } never executed: end of block | 0 | ||||||||||||||||||
520 | if (!policy) {
| 0 | ||||||||||||||||||
521 | TSerr(TS_F_TS_RESP_GET_POLICY, TS_R_UNACCEPTABLE_POLICY); | - | ||||||||||||||||||
522 | TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, | - | ||||||||||||||||||
523 | "Requested policy is not " "supported."); | - | ||||||||||||||||||
524 | TS_RESP_CTX_add_failure_info(ctx, TS_INFO_UNACCEPTED_POLICY); | - | ||||||||||||||||||
525 | } never executed: end of block | 0 | ||||||||||||||||||
526 | return policy; never executed: return policy; | 0 | ||||||||||||||||||
527 | } | - | ||||||||||||||||||
528 | - | |||||||||||||||||||
529 | /* Creates the TS_TST_INFO object based on the settings of the context. */ | - | ||||||||||||||||||
530 | static TS_TST_INFO *ts_RESP_create_tst_info(TS_RESP_CTX *ctx, | - | ||||||||||||||||||
531 | ASN1_OBJECT *policy) | - | ||||||||||||||||||
532 | { | - | ||||||||||||||||||
533 | int result = 0; | - | ||||||||||||||||||
534 | TS_TST_INFO *tst_info = NULL; | - | ||||||||||||||||||
535 | ASN1_INTEGER *serial = NULL; | - | ||||||||||||||||||
536 | ASN1_GENERALIZEDTIME *asn1_time = NULL; | - | ||||||||||||||||||
537 | long sec, usec; | - | ||||||||||||||||||
538 | TS_ACCURACY *accuracy = NULL; | - | ||||||||||||||||||
539 | const ASN1_INTEGER *nonce; | - | ||||||||||||||||||
540 | GENERAL_NAME *tsa_name = NULL; | - | ||||||||||||||||||
541 | - | |||||||||||||||||||
542 | if ((tst_info = TS_TST_INFO_new()) == NULL)
| 0 | ||||||||||||||||||
543 | goto end; never executed: goto end; | 0 | ||||||||||||||||||
544 | if (!TS_TST_INFO_set_version(tst_info, 1))
| 0 | ||||||||||||||||||
545 | goto end; never executed: goto end; | 0 | ||||||||||||||||||
546 | if (!TS_TST_INFO_set_policy_id(tst_info, policy))
| 0 | ||||||||||||||||||
547 | goto end; never executed: goto end; | 0 | ||||||||||||||||||
548 | if (!TS_TST_INFO_set_msg_imprint(tst_info, ctx->request->msg_imprint))
| 0 | ||||||||||||||||||
549 | goto end; never executed: goto end; | 0 | ||||||||||||||||||
550 | if ((serial = ctx->serial_cb(ctx, ctx->serial_cb_data)) == NULL
| 0 | ||||||||||||||||||
551 | || !TS_TST_INFO_set_serial(tst_info, serial))
| 0 | ||||||||||||||||||
552 | goto end; never executed: goto end; | 0 | ||||||||||||||||||
553 | if (!ctx->time_cb(ctx, ctx->time_cb_data, &sec, &usec)
| 0 | ||||||||||||||||||
554 | || (asn1_time =
| 0 | ||||||||||||||||||
555 | TS_RESP_set_genTime_with_precision(NULL, sec, usec,
| 0 | ||||||||||||||||||
556 | ctx->clock_precision_digits)) == NULL
| 0 | ||||||||||||||||||
557 | || !TS_TST_INFO_set_time(tst_info, asn1_time))
| 0 | ||||||||||||||||||
558 | goto end; never executed: goto end; | 0 | ||||||||||||||||||
559 | - | |||||||||||||||||||
560 | if ((ctx->seconds || ctx->millis || ctx->micros)
| 0 | ||||||||||||||||||
561 | && (accuracy = TS_ACCURACY_new()) == NULL)
| 0 | ||||||||||||||||||
562 | goto end; never executed: goto end; | 0 | ||||||||||||||||||
563 | if (ctx->seconds && !TS_ACCURACY_set_seconds(accuracy, ctx->seconds))
| 0 | ||||||||||||||||||
564 | goto end; never executed: goto end; | 0 | ||||||||||||||||||
565 | if (ctx->millis && !TS_ACCURACY_set_millis(accuracy, ctx->millis))
| 0 | ||||||||||||||||||
566 | goto end; never executed: goto end; | 0 | ||||||||||||||||||
567 | if (ctx->micros && !TS_ACCURACY_set_micros(accuracy, ctx->micros))
| 0 | ||||||||||||||||||
568 | goto end; never executed: goto end; | 0 | ||||||||||||||||||
569 | if (accuracy && !TS_TST_INFO_set_accuracy(tst_info, accuracy))
| 0 | ||||||||||||||||||
570 | goto end; never executed: goto end; | 0 | ||||||||||||||||||
571 | - | |||||||||||||||||||
572 | if ((ctx->flags & TS_ORDERING)
| 0 | ||||||||||||||||||
573 | && !TS_TST_INFO_set_ordering(tst_info, 1))
| 0 | ||||||||||||||||||
574 | goto end; never executed: goto end; | 0 | ||||||||||||||||||
575 | - | |||||||||||||||||||
576 | if ((nonce = ctx->request->nonce) != NULL
| 0 | ||||||||||||||||||
577 | && !TS_TST_INFO_set_nonce(tst_info, nonce))
| 0 | ||||||||||||||||||
578 | goto end; never executed: goto end; | 0 | ||||||||||||||||||
579 | - | |||||||||||||||||||
580 | if (ctx->flags & TS_TSA_NAME) {
| 0 | ||||||||||||||||||
581 | if ((tsa_name = GENERAL_NAME_new()) == NULL)
| 0 | ||||||||||||||||||
582 | goto end; never executed: goto end; | 0 | ||||||||||||||||||
583 | tsa_name->type = GEN_DIRNAME; | - | ||||||||||||||||||
584 | tsa_name->d.dirn = | - | ||||||||||||||||||
585 | X509_NAME_dup(X509_get_subject_name(ctx->signer_cert)); | - | ||||||||||||||||||
586 | if (!tsa_name->d.dirn)
| 0 | ||||||||||||||||||
587 | goto end; never executed: goto end; | 0 | ||||||||||||||||||
588 | if (!TS_TST_INFO_set_tsa(tst_info, tsa_name))
| 0 | ||||||||||||||||||
589 | goto end; never executed: goto end; | 0 | ||||||||||||||||||
590 | } never executed: end of block | 0 | ||||||||||||||||||
591 | - | |||||||||||||||||||
592 | result = 1; | - | ||||||||||||||||||
593 | end: code before this statement never executed: end: | 0 | ||||||||||||||||||
594 | if (!result) {
| 0 | ||||||||||||||||||
595 | TS_TST_INFO_free(tst_info); | - | ||||||||||||||||||
596 | tst_info = NULL; | - | ||||||||||||||||||
597 | TSerr(TS_F_TS_RESP_CREATE_TST_INFO, TS_R_TST_INFO_SETUP_ERROR); | - | ||||||||||||||||||
598 | TS_RESP_CTX_set_status_info_cond(ctx, TS_STATUS_REJECTION, | - | ||||||||||||||||||
599 | "Error during TSTInfo " | - | ||||||||||||||||||
600 | "generation."); | - | ||||||||||||||||||
601 | } never executed: end of block | 0 | ||||||||||||||||||
602 | GENERAL_NAME_free(tsa_name); | - | ||||||||||||||||||
603 | TS_ACCURACY_free(accuracy); | - | ||||||||||||||||||
604 | ASN1_GENERALIZEDTIME_free(asn1_time); | - | ||||||||||||||||||
605 | ASN1_INTEGER_free(serial); | - | ||||||||||||||||||
606 | - | |||||||||||||||||||
607 | return tst_info; never executed: return tst_info; | 0 | ||||||||||||||||||
608 | } | - | ||||||||||||||||||
609 | - | |||||||||||||||||||
610 | /* Processing the extensions of the request. */ | - | ||||||||||||||||||
611 | static int ts_RESP_process_extensions(TS_RESP_CTX *ctx) | - | ||||||||||||||||||
612 | { | - | ||||||||||||||||||
613 | STACK_OF(X509_EXTENSION) *exts = ctx->request->extensions; | - | ||||||||||||||||||
614 | int i; | - | ||||||||||||||||||
615 | int ok = 1; | - | ||||||||||||||||||
616 | - | |||||||||||||||||||
617 | for (i = 0; ok && i < sk_X509_EXTENSION_num(exts); ++i) {
| 0 | ||||||||||||||||||
618 | X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i); | - | ||||||||||||||||||
619 | /* | - | ||||||||||||||||||
620 | * The last argument was previously (void *)ctx->extension_cb, | - | ||||||||||||||||||
621 | * but ISO C doesn't permit converting a function pointer to void *. | - | ||||||||||||||||||
622 | * For lack of better information, I'm placing a NULL there instead. | - | ||||||||||||||||||
623 | * The callback can pick its own address out from the ctx anyway... | - | ||||||||||||||||||
624 | */ | - | ||||||||||||||||||
625 | ok = (*ctx->extension_cb) (ctx, ext, NULL); | - | ||||||||||||||||||
626 | } never executed: end of block | 0 | ||||||||||||||||||
627 | - | |||||||||||||||||||
628 | return ok; never executed: return ok; | 0 | ||||||||||||||||||
629 | } | - | ||||||||||||||||||
630 | - | |||||||||||||||||||
631 | /* Functions for signing the TS_TST_INFO structure of the context. */ | - | ||||||||||||||||||
632 | static int ts_RESP_sign(TS_RESP_CTX *ctx) | - | ||||||||||||||||||
633 | { | - | ||||||||||||||||||
634 | int ret = 0; | - | ||||||||||||||||||
635 | PKCS7 *p7 = NULL; | - | ||||||||||||||||||
636 | PKCS7_SIGNER_INFO *si; | - | ||||||||||||||||||
637 | STACK_OF(X509) *certs; /* Certificates to include in sc. */ | - | ||||||||||||||||||
638 | ESS_SIGNING_CERT_V2 *sc2 = NULL; | - | ||||||||||||||||||
639 | ESS_SIGNING_CERT *sc = NULL; | - | ||||||||||||||||||
640 | ASN1_OBJECT *oid; | - | ||||||||||||||||||
641 | BIO *p7bio = NULL; | - | ||||||||||||||||||
642 | int i; | - | ||||||||||||||||||
643 | - | |||||||||||||||||||
644 | if (!X509_check_private_key(ctx->signer_cert, ctx->signer_key)) {
| 0 | ||||||||||||||||||
645 | TSerr(TS_F_TS_RESP_SIGN, TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); | - | ||||||||||||||||||
646 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
647 | } | - | ||||||||||||||||||
648 | - | |||||||||||||||||||
649 | if ((p7 = PKCS7_new()) == NULL) {
| 0 | ||||||||||||||||||
650 | TSerr(TS_F_TS_RESP_SIGN, ERR_R_MALLOC_FAILURE); | - | ||||||||||||||||||
651 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
652 | } | - | ||||||||||||||||||
653 | if (!PKCS7_set_type(p7, NID_pkcs7_signed))
| 0 | ||||||||||||||||||
654 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
655 | if (!ASN1_INTEGER_set(p7->d.sign->version, 3))
| 0 | ||||||||||||||||||
656 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
657 | - | |||||||||||||||||||
658 | if (ctx->request->cert_req) {
| 0 | ||||||||||||||||||
659 | PKCS7_add_certificate(p7, ctx->signer_cert); | - | ||||||||||||||||||
660 | if (ctx->certs) {
| 0 | ||||||||||||||||||
661 | for (i = 0; i < sk_X509_num(ctx->certs); ++i) {
| 0 | ||||||||||||||||||
662 | X509 *cert = sk_X509_value(ctx->certs, i); | - | ||||||||||||||||||
663 | PKCS7_add_certificate(p7, cert); | - | ||||||||||||||||||
664 | } never executed: end of block | 0 | ||||||||||||||||||
665 | } never executed: end of block | 0 | ||||||||||||||||||
666 | } never executed: end of block | 0 | ||||||||||||||||||
667 | - | |||||||||||||||||||
668 | if ((si = PKCS7_add_signature(p7, ctx->signer_cert,
| 0 | ||||||||||||||||||
669 | ctx->signer_key, ctx->signer_md)) == NULL) {
| 0 | ||||||||||||||||||
670 | TSerr(TS_F_TS_RESP_SIGN, TS_R_PKCS7_ADD_SIGNATURE_ERROR); | - | ||||||||||||||||||
671 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
672 | } | - | ||||||||||||||||||
673 | - | |||||||||||||||||||
674 | oid = OBJ_nid2obj(NID_id_smime_ct_TSTInfo); | - | ||||||||||||||||||
675 | if (!PKCS7_add_signed_attribute(si, NID_pkcs9_contentType,
| 0 | ||||||||||||||||||
676 | V_ASN1_OBJECT, oid)) {
| 0 | ||||||||||||||||||
677 | TSerr(TS_F_TS_RESP_SIGN, TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR); | - | ||||||||||||||||||
678 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
679 | } | - | ||||||||||||||||||
680 | - | |||||||||||||||||||
681 | certs = ctx->flags & TS_ESS_CERT_ID_CHAIN ? ctx->certs : NULL;
| 0 | ||||||||||||||||||
682 | if (ctx->ess_cert_id_digest == NULL
| 0 | ||||||||||||||||||
683 | || ctx->ess_cert_id_digest == EVP_sha1()) {
| 0 | ||||||||||||||||||
684 | if ((sc = ess_SIGNING_CERT_new_init(ctx->signer_cert, certs)) == NULL)
| 0 | ||||||||||||||||||
685 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
686 | - | |||||||||||||||||||
687 | if (!ess_add_signing_cert(si, sc)) {
| 0 | ||||||||||||||||||
688 | TSerr(TS_F_TS_RESP_SIGN, TS_R_ESS_ADD_SIGNING_CERT_ERROR); | - | ||||||||||||||||||
689 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
690 | } | - | ||||||||||||||||||
691 | } else { never executed: end of block | 0 | ||||||||||||||||||
692 | sc2 = ess_signing_cert_v2_new_init(ctx->ess_cert_id_digest, | - | ||||||||||||||||||
693 | ctx->signer_cert, certs); | - | ||||||||||||||||||
694 | if (sc2 == NULL)
| 0 | ||||||||||||||||||
695 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
696 | - | |||||||||||||||||||
697 | if (!ess_add_signing_cert_v2(si, sc2)) {
| 0 | ||||||||||||||||||
698 | TSerr(TS_F_TS_RESP_SIGN, TS_R_ESS_ADD_SIGNING_CERT_V2_ERROR); | - | ||||||||||||||||||
699 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
700 | } | - | ||||||||||||||||||
701 | } never executed: end of block | 0 | ||||||||||||||||||
702 | - | |||||||||||||||||||
703 | if (!ts_TST_INFO_content_new(p7))
| 0 | ||||||||||||||||||
704 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
705 | if ((p7bio = PKCS7_dataInit(p7, NULL)) == NULL) {
| 0 | ||||||||||||||||||
706 | TSerr(TS_F_TS_RESP_SIGN, ERR_R_MALLOC_FAILURE); | - | ||||||||||||||||||
707 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
708 | } | - | ||||||||||||||||||
709 | if (!i2d_TS_TST_INFO_bio(p7bio, ctx->tst_info)) {
| 0 | ||||||||||||||||||
710 | TSerr(TS_F_TS_RESP_SIGN, TS_R_TS_DATASIGN); | - | ||||||||||||||||||
711 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
712 | } | - | ||||||||||||||||||
713 | if (!PKCS7_dataFinal(p7, p7bio)) {
| 0 | ||||||||||||||||||
714 | TSerr(TS_F_TS_RESP_SIGN, TS_R_TS_DATASIGN); | - | ||||||||||||||||||
715 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
716 | } | - | ||||||||||||||||||
717 | TS_RESP_set_tst_info(ctx->response, p7, ctx->tst_info); | - | ||||||||||||||||||
718 | p7 = NULL; /* Ownership is lost. */ | - | ||||||||||||||||||
719 | ctx->tst_info = NULL; /* Ownership is lost. */ | - | ||||||||||||||||||
720 | - | |||||||||||||||||||
721 | ret = 1; | - | ||||||||||||||||||
722 | err: code before this statement never executed: err: | 0 | ||||||||||||||||||
723 | if (!ret)
| 0 | ||||||||||||||||||
724 | TS_RESP_CTX_set_status_info_cond(ctx, TS_STATUS_REJECTION, never executed: TS_RESP_CTX_set_status_info_cond(ctx, 2, "Error during signature " "generation."); | 0 | ||||||||||||||||||
725 | "Error during signature " never executed: TS_RESP_CTX_set_status_info_cond(ctx, 2, "Error during signature " "generation."); | 0 | ||||||||||||||||||
726 | "generation."); never executed: TS_RESP_CTX_set_status_info_cond(ctx, 2, "Error during signature " "generation."); | 0 | ||||||||||||||||||
727 | BIO_free_all(p7bio); | - | ||||||||||||||||||
728 | ESS_SIGNING_CERT_V2_free(sc2); | - | ||||||||||||||||||
729 | ESS_SIGNING_CERT_free(sc); | - | ||||||||||||||||||
730 | PKCS7_free(p7); | - | ||||||||||||||||||
731 | return ret; never executed: return ret; | 0 | ||||||||||||||||||
732 | } | - | ||||||||||||||||||
733 | - | |||||||||||||||||||
734 | static ESS_SIGNING_CERT *ess_SIGNING_CERT_new_init(X509 *signcert, | - | ||||||||||||||||||
735 | STACK_OF(X509) *certs) | - | ||||||||||||||||||
736 | { | - | ||||||||||||||||||
737 | ESS_CERT_ID *cid; | - | ||||||||||||||||||
738 | ESS_SIGNING_CERT *sc = NULL; | - | ||||||||||||||||||
739 | int i; | - | ||||||||||||||||||
740 | - | |||||||||||||||||||
741 | if ((sc = ESS_SIGNING_CERT_new()) == NULL)
| 0 | ||||||||||||||||||
742 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
743 | if (sc->cert_ids == NULL
| 0 | ||||||||||||||||||
744 | && (sc->cert_ids = sk_ESS_CERT_ID_new_null()) == NULL)
| 0 | ||||||||||||||||||
745 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
746 | - | |||||||||||||||||||
747 | if ((cid = ess_CERT_ID_new_init(signcert, 0)) == NULL
| 0 | ||||||||||||||||||
748 | || !sk_ESS_CERT_ID_push(sc->cert_ids, cid))
| 0 | ||||||||||||||||||
749 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
750 | for (i = 0; i < sk_X509_num(certs); ++i) {
| 0 | ||||||||||||||||||
751 | X509 *cert = sk_X509_value(certs, i); | - | ||||||||||||||||||
752 | if ((cid = ess_CERT_ID_new_init(cert, 1)) == NULL
| 0 | ||||||||||||||||||
753 | || !sk_ESS_CERT_ID_push(sc->cert_ids, cid))
| 0 | ||||||||||||||||||
754 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
755 | } never executed: end of block | 0 | ||||||||||||||||||
756 | - | |||||||||||||||||||
757 | return sc; never executed: return sc; | 0 | ||||||||||||||||||
758 | err: | - | ||||||||||||||||||
759 | ESS_SIGNING_CERT_free(sc); | - | ||||||||||||||||||
760 | TSerr(TS_F_ESS_SIGNING_CERT_NEW_INIT, ERR_R_MALLOC_FAILURE); | - | ||||||||||||||||||
761 | return NULL; never executed: return ((void *)0) ; | 0 | ||||||||||||||||||
762 | } | - | ||||||||||||||||||
763 | - | |||||||||||||||||||
764 | static ESS_CERT_ID *ess_CERT_ID_new_init(X509 *cert, int issuer_needed) | - | ||||||||||||||||||
765 | { | - | ||||||||||||||||||
766 | ESS_CERT_ID *cid = NULL; | - | ||||||||||||||||||
767 | GENERAL_NAME *name = NULL; | - | ||||||||||||||||||
768 | unsigned char cert_sha1[SHA_DIGEST_LENGTH]; | - | ||||||||||||||||||
769 | - | |||||||||||||||||||
770 | /* Call for side-effect of computing hash and caching extensions */ | - | ||||||||||||||||||
771 | X509_check_purpose(cert, -1, 0); | - | ||||||||||||||||||
772 | if ((cid = ESS_CERT_ID_new()) == NULL)
| 0 | ||||||||||||||||||
773 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
774 | X509_digest(cert, EVP_sha1(), cert_sha1, NULL); | - | ||||||||||||||||||
775 | if (!ASN1_OCTET_STRING_set(cid->hash, cert_sha1, SHA_DIGEST_LENGTH))
| 0 | ||||||||||||||||||
776 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
777 | - | |||||||||||||||||||
778 | /* Setting the issuer/serial if requested. */ | - | ||||||||||||||||||
779 | if (issuer_needed) {
| 0 | ||||||||||||||||||
780 | if (cid->issuer_serial == NULL
| 0 | ||||||||||||||||||
781 | && (cid->issuer_serial = ESS_ISSUER_SERIAL_new()) == NULL)
| 0 | ||||||||||||||||||
782 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
783 | if ((name = GENERAL_NAME_new()) == NULL)
| 0 | ||||||||||||||||||
784 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
785 | name->type = GEN_DIRNAME; | - | ||||||||||||||||||
786 | if ((name->d.dirn = X509_NAME_dup(X509_get_issuer_name(cert))) == NULL)
| 0 | ||||||||||||||||||
787 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
788 | if (!sk_GENERAL_NAME_push(cid->issuer_serial->issuer, name))
| 0 | ||||||||||||||||||
789 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
790 | name = NULL; /* Ownership is lost. */ | - | ||||||||||||||||||
791 | ASN1_INTEGER_free(cid->issuer_serial->serial); | - | ||||||||||||||||||
792 | if (!(cid->issuer_serial->serial =
| 0 | ||||||||||||||||||
793 | ASN1_INTEGER_dup(X509_get_serialNumber(cert))))
| 0 | ||||||||||||||||||
794 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
795 | } never executed: end of block | 0 | ||||||||||||||||||
796 | - | |||||||||||||||||||
797 | return cid; never executed: return cid; | 0 | ||||||||||||||||||
798 | err: | - | ||||||||||||||||||
799 | GENERAL_NAME_free(name); | - | ||||||||||||||||||
800 | ESS_CERT_ID_free(cid); | - | ||||||||||||||||||
801 | TSerr(TS_F_ESS_CERT_ID_NEW_INIT, ERR_R_MALLOC_FAILURE); | - | ||||||||||||||||||
802 | return NULL; never executed: return ((void *)0) ; | 0 | ||||||||||||||||||
803 | } | - | ||||||||||||||||||
804 | - | |||||||||||||||||||
805 | static int ts_TST_INFO_content_new(PKCS7 *p7) | - | ||||||||||||||||||
806 | { | - | ||||||||||||||||||
807 | PKCS7 *ret = NULL; | - | ||||||||||||||||||
808 | ASN1_OCTET_STRING *octet_string = NULL; | - | ||||||||||||||||||
809 | - | |||||||||||||||||||
810 | /* Create new encapsulated NID_id_smime_ct_TSTInfo content. */ | - | ||||||||||||||||||
811 | if ((ret = PKCS7_new()) == NULL)
| 0 | ||||||||||||||||||
812 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
813 | if ((ret->d.other = ASN1_TYPE_new()) == NULL)
| 0 | ||||||||||||||||||
814 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
815 | ret->type = OBJ_nid2obj(NID_id_smime_ct_TSTInfo); | - | ||||||||||||||||||
816 | if ((octet_string = ASN1_OCTET_STRING_new()) == NULL)
| 0 | ||||||||||||||||||
817 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
818 | ASN1_TYPE_set(ret->d.other, V_ASN1_OCTET_STRING, octet_string); | - | ||||||||||||||||||
819 | octet_string = NULL; | - | ||||||||||||||||||
820 | - | |||||||||||||||||||
821 | /* Add encapsulated content to signed PKCS7 structure. */ | - | ||||||||||||||||||
822 | if (!PKCS7_set_content(p7, ret))
| 0 | ||||||||||||||||||
823 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
824 | - | |||||||||||||||||||
825 | return 1; never executed: return 1; | 0 | ||||||||||||||||||
826 | err: | - | ||||||||||||||||||
827 | ASN1_OCTET_STRING_free(octet_string); | - | ||||||||||||||||||
828 | PKCS7_free(ret); | - | ||||||||||||||||||
829 | return 0; never executed: return 0; | 0 | ||||||||||||||||||
830 | } | - | ||||||||||||||||||
831 | - | |||||||||||||||||||
832 | static int ess_add_signing_cert(PKCS7_SIGNER_INFO *si, ESS_SIGNING_CERT *sc) | - | ||||||||||||||||||
833 | { | - | ||||||||||||||||||
834 | ASN1_STRING *seq = NULL; | - | ||||||||||||||||||
835 | unsigned char *p, *pp = NULL; | - | ||||||||||||||||||
836 | int len; | - | ||||||||||||||||||
837 | - | |||||||||||||||||||
838 | len = i2d_ESS_SIGNING_CERT(sc, NULL); | - | ||||||||||||||||||
839 | if ((pp = OPENSSL_malloc(len)) == NULL) {
| 0 | ||||||||||||||||||
840 | TSerr(TS_F_ESS_ADD_SIGNING_CERT, ERR_R_MALLOC_FAILURE); | - | ||||||||||||||||||
841 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
842 | } | - | ||||||||||||||||||
843 | p = pp; | - | ||||||||||||||||||
844 | i2d_ESS_SIGNING_CERT(sc, &p); | - | ||||||||||||||||||
845 | if ((seq = ASN1_STRING_new()) == NULL || !ASN1_STRING_set(seq, pp, len)) {
| 0 | ||||||||||||||||||
846 | TSerr(TS_F_ESS_ADD_SIGNING_CERT, ERR_R_MALLOC_FAILURE); | - | ||||||||||||||||||
847 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
848 | } | - | ||||||||||||||||||
849 | OPENSSL_free(pp); | - | ||||||||||||||||||
850 | pp = NULL; | - | ||||||||||||||||||
851 | return PKCS7_add_signed_attribute(si, never executed: return PKCS7_add_signed_attribute(si, 223, 16, seq); | 0 | ||||||||||||||||||
852 | NID_id_smime_aa_signingCertificate, never executed: return PKCS7_add_signed_attribute(si, 223, 16, seq); | 0 | ||||||||||||||||||
853 | V_ASN1_SEQUENCE, seq); never executed: return PKCS7_add_signed_attribute(si, 223, 16, seq); | 0 | ||||||||||||||||||
854 | err: | - | ||||||||||||||||||
855 | ASN1_STRING_free(seq); | - | ||||||||||||||||||
856 | OPENSSL_free(pp); | - | ||||||||||||||||||
857 | - | |||||||||||||||||||
858 | return 0; never executed: return 0; | 0 | ||||||||||||||||||
859 | } | - | ||||||||||||||||||
860 | - | |||||||||||||||||||
861 | static ESS_SIGNING_CERT_V2 *ess_signing_cert_v2_new_init(const EVP_MD *hash_alg, | - | ||||||||||||||||||
862 | X509 *signcert, | - | ||||||||||||||||||
863 | STACK_OF(X509) *certs) | - | ||||||||||||||||||
864 | { | - | ||||||||||||||||||
865 | ESS_CERT_ID_V2 *cid = NULL; | - | ||||||||||||||||||
866 | ESS_SIGNING_CERT_V2 *sc = NULL; | - | ||||||||||||||||||
867 | int i; | - | ||||||||||||||||||
868 | - | |||||||||||||||||||
869 | if ((sc = ESS_SIGNING_CERT_V2_new()) == NULL)
| 0 | ||||||||||||||||||
870 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
871 | if ((cid = ess_cert_id_v2_new_init(hash_alg, signcert, 0)) == NULL)
| 0 | ||||||||||||||||||
872 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
873 | if (!sk_ESS_CERT_ID_V2_push(sc->cert_ids, cid))
| 0 | ||||||||||||||||||
874 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
875 | cid = NULL; | - | ||||||||||||||||||
876 | - | |||||||||||||||||||
877 | for (i = 0; i < sk_X509_num(certs); ++i) {
| 0 | ||||||||||||||||||
878 | X509 *cert = sk_X509_value(certs, i); | - | ||||||||||||||||||
879 | - | |||||||||||||||||||
880 | if ((cid = ess_cert_id_v2_new_init(hash_alg, cert, 1)) == NULL)
| 0 | ||||||||||||||||||
881 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
882 | if (!sk_ESS_CERT_ID_V2_push(sc->cert_ids, cid))
| 0 | ||||||||||||||||||
883 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
884 | cid = NULL; | - | ||||||||||||||||||
885 | } never executed: end of block | 0 | ||||||||||||||||||
886 | - | |||||||||||||||||||
887 | return sc; never executed: return sc; | 0 | ||||||||||||||||||
888 | err: | - | ||||||||||||||||||
889 | ESS_SIGNING_CERT_V2_free(sc); | - | ||||||||||||||||||
890 | ESS_CERT_ID_V2_free(cid); | - | ||||||||||||||||||
891 | TSerr(TS_F_ESS_SIGNING_CERT_V2_NEW_INIT, ERR_R_MALLOC_FAILURE); | - | ||||||||||||||||||
892 | return NULL; never executed: return ((void *)0) ; | 0 | ||||||||||||||||||
893 | } | - | ||||||||||||||||||
894 | - | |||||||||||||||||||
895 | static ESS_CERT_ID_V2 *ess_cert_id_v2_new_init(const EVP_MD *hash_alg, | - | ||||||||||||||||||
896 | X509 *cert, int issuer_needed) | - | ||||||||||||||||||
897 | { | - | ||||||||||||||||||
898 | ESS_CERT_ID_V2 *cid = NULL; | - | ||||||||||||||||||
899 | GENERAL_NAME *name = NULL; | - | ||||||||||||||||||
900 | unsigned char hash[EVP_MAX_MD_SIZE]; | - | ||||||||||||||||||
901 | unsigned int hash_len = sizeof(hash); | - | ||||||||||||||||||
902 | X509_ALGOR *alg = NULL; | - | ||||||||||||||||||
903 | - | |||||||||||||||||||
904 | memset(hash, 0, sizeof(hash)); | - | ||||||||||||||||||
905 | - | |||||||||||||||||||
906 | if ((cid = ESS_CERT_ID_V2_new()) == NULL)
| 0 | ||||||||||||||||||
907 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
908 | - | |||||||||||||||||||
909 | if (hash_alg != EVP_sha256()) {
| 0 | ||||||||||||||||||
910 | alg = X509_ALGOR_new(); | - | ||||||||||||||||||
911 | if (alg == NULL)
| 0 | ||||||||||||||||||
912 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
913 | X509_ALGOR_set_md(alg, hash_alg); | - | ||||||||||||||||||
914 | if (alg->algorithm == NULL)
| 0 | ||||||||||||||||||
915 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
916 | cid->hash_alg = alg; | - | ||||||||||||||||||
917 | alg = NULL; | - | ||||||||||||||||||
918 | } else { never executed: end of block | 0 | ||||||||||||||||||
919 | cid->hash_alg = NULL; | - | ||||||||||||||||||
920 | } never executed: end of block | 0 | ||||||||||||||||||
921 | - | |||||||||||||||||||
922 | if (!X509_digest(cert, hash_alg, hash, &hash_len))
| 0 | ||||||||||||||||||
923 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
924 | - | |||||||||||||||||||
925 | if (!ASN1_OCTET_STRING_set(cid->hash, hash, hash_len))
| 0 | ||||||||||||||||||
926 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
927 | - | |||||||||||||||||||
928 | if (issuer_needed) {
| 0 | ||||||||||||||||||
929 | if ((cid->issuer_serial = ESS_ISSUER_SERIAL_new()) == NULL)
| 0 | ||||||||||||||||||
930 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
931 | if ((name = GENERAL_NAME_new()) == NULL)
| 0 | ||||||||||||||||||
932 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
933 | name->type = GEN_DIRNAME; | - | ||||||||||||||||||
934 | if ((name->d.dirn = X509_NAME_dup(X509_get_issuer_name(cert))) == NULL)
| 0 | ||||||||||||||||||
935 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
936 | if (!sk_GENERAL_NAME_push(cid->issuer_serial->issuer, name))
| 0 | ||||||||||||||||||
937 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
938 | name = NULL; /* Ownership is lost. */ | - | ||||||||||||||||||
939 | ASN1_INTEGER_free(cid->issuer_serial->serial); | - | ||||||||||||||||||
940 | cid->issuer_serial->serial = | - | ||||||||||||||||||
941 | ASN1_INTEGER_dup(X509_get_serialNumber(cert)); | - | ||||||||||||||||||
942 | if (cid->issuer_serial->serial == NULL)
| 0 | ||||||||||||||||||
943 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
944 | } never executed: end of block | 0 | ||||||||||||||||||
945 | - | |||||||||||||||||||
946 | return cid; never executed: return cid; | 0 | ||||||||||||||||||
947 | err: | - | ||||||||||||||||||
948 | X509_ALGOR_free(alg); | - | ||||||||||||||||||
949 | GENERAL_NAME_free(name); | - | ||||||||||||||||||
950 | ESS_CERT_ID_V2_free(cid); | - | ||||||||||||||||||
951 | TSerr(TS_F_ESS_CERT_ID_V2_NEW_INIT, ERR_R_MALLOC_FAILURE); | - | ||||||||||||||||||
952 | return NULL; never executed: return ((void *)0) ; | 0 | ||||||||||||||||||
953 | } | - | ||||||||||||||||||
954 | - | |||||||||||||||||||
955 | static int ess_add_signing_cert_v2(PKCS7_SIGNER_INFO *si, | - | ||||||||||||||||||
956 | ESS_SIGNING_CERT_V2 *sc) | - | ||||||||||||||||||
957 | { | - | ||||||||||||||||||
958 | ASN1_STRING *seq = NULL; | - | ||||||||||||||||||
959 | unsigned char *p, *pp = NULL; | - | ||||||||||||||||||
960 | int len = i2d_ESS_SIGNING_CERT_V2(sc, NULL); | - | ||||||||||||||||||
961 | - | |||||||||||||||||||
962 | if ((pp = OPENSSL_malloc(len)) == NULL) {
| 0 | ||||||||||||||||||
963 | TSerr(TS_F_ESS_ADD_SIGNING_CERT_V2, ERR_R_MALLOC_FAILURE); | - | ||||||||||||||||||
964 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
965 | } | - | ||||||||||||||||||
966 | - | |||||||||||||||||||
967 | p = pp; | - | ||||||||||||||||||
968 | i2d_ESS_SIGNING_CERT_V2(sc, &p); | - | ||||||||||||||||||
969 | if ((seq = ASN1_STRING_new()) == NULL || !ASN1_STRING_set(seq, pp, len)) {
| 0 | ||||||||||||||||||
970 | TSerr(TS_F_ESS_ADD_SIGNING_CERT_V2, ERR_R_MALLOC_FAILURE); | - | ||||||||||||||||||
971 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
972 | } | - | ||||||||||||||||||
973 | - | |||||||||||||||||||
974 | OPENSSL_free(pp); | - | ||||||||||||||||||
975 | pp = NULL; | - | ||||||||||||||||||
976 | return PKCS7_add_signed_attribute(si, never executed: return PKCS7_add_signed_attribute(si, 1086, 16, seq); | 0 | ||||||||||||||||||
977 | NID_id_smime_aa_signingCertificateV2, never executed: return PKCS7_add_signed_attribute(si, 1086, 16, seq); | 0 | ||||||||||||||||||
978 | V_ASN1_SEQUENCE, seq); never executed: return PKCS7_add_signed_attribute(si, 1086, 16, seq); | 0 | ||||||||||||||||||
979 | err: | - | ||||||||||||||||||
980 | ASN1_STRING_free(seq); | - | ||||||||||||||||||
981 | OPENSSL_free(pp); | - | ||||||||||||||||||
982 | return 0; never executed: return 0; | 0 | ||||||||||||||||||
983 | } | - | ||||||||||||||||||
984 | - | |||||||||||||||||||
985 | static ASN1_GENERALIZEDTIME *TS_RESP_set_genTime_with_precision( | - | ||||||||||||||||||
986 | ASN1_GENERALIZEDTIME *asn1_time, long sec, long usec, | - | ||||||||||||||||||
987 | unsigned precision) | - | ||||||||||||||||||
988 | { | - | ||||||||||||||||||
989 | time_t time_sec = (time_t)sec; | - | ||||||||||||||||||
990 | struct tm *tm = NULL, tm_result; | - | ||||||||||||||||||
991 | char genTime_str[17 + TS_MAX_CLOCK_PRECISION_DIGITS]; | - | ||||||||||||||||||
992 | char *p = genTime_str; | - | ||||||||||||||||||
993 | char *p_end = genTime_str + sizeof(genTime_str); | - | ||||||||||||||||||
994 | - | |||||||||||||||||||
995 | if (precision > TS_MAX_CLOCK_PRECISION_DIGITS)
| 0 | ||||||||||||||||||
996 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
997 | - | |||||||||||||||||||
998 | if ((tm = OPENSSL_gmtime(&time_sec, &tm_result)) == NULL)
| 0 | ||||||||||||||||||
999 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
1000 | - | |||||||||||||||||||
1001 | /* | - | ||||||||||||||||||
1002 | * Put "genTime_str" in GeneralizedTime format. We work around the | - | ||||||||||||||||||
1003 | * restrictions imposed by rfc3280 (i.e. "GeneralizedTime values MUST | - | ||||||||||||||||||
1004 | * NOT include fractional seconds") and OpenSSL related functions to | - | ||||||||||||||||||
1005 | * meet the rfc3161 requirement: "GeneralizedTime syntax can include | - | ||||||||||||||||||
1006 | * fraction-of-second details". | - | ||||||||||||||||||
1007 | */ | - | ||||||||||||||||||
1008 | p += BIO_snprintf(p, p_end - p, | - | ||||||||||||||||||
1009 | "%04d%02d%02d%02d%02d%02d", | - | ||||||||||||||||||
1010 | tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, | - | ||||||||||||||||||
1011 | tm->tm_hour, tm->tm_min, tm->tm_sec); | - | ||||||||||||||||||
1012 | if (precision > 0) {
| 0 | ||||||||||||||||||
1013 | BIO_snprintf(p, 2 + precision, ".%06ld", usec); | - | ||||||||||||||||||
1014 | p += strlen(p); | - | ||||||||||||||||||
1015 | - | |||||||||||||||||||
1016 | /* | - | ||||||||||||||||||
1017 | * To make things a bit harder, X.690 | ISO/IEC 8825-1 provides the | - | ||||||||||||||||||
1018 | * following restrictions for a DER-encoding, which OpenSSL | - | ||||||||||||||||||
1019 | * (specifically ASN1_GENERALIZEDTIME_check() function) doesn't | - | ||||||||||||||||||
1020 | * support: "The encoding MUST terminate with a "Z" (which means | - | ||||||||||||||||||
1021 | * "Zulu" time). The decimal point element, if present, MUST be the | - | ||||||||||||||||||
1022 | * point option ".". The fractional-seconds elements, if present, | - | ||||||||||||||||||
1023 | * MUST omit all trailing 0's; if the elements correspond to 0, they | - | ||||||||||||||||||
1024 | * MUST be wholly omitted, and the decimal point element also MUST be | - | ||||||||||||||||||
1025 | * omitted." | - | ||||||||||||||||||
1026 | */ | - | ||||||||||||||||||
1027 | /* | - | ||||||||||||||||||
1028 | * Remove trailing zeros. The dot guarantees the exit condition of | - | ||||||||||||||||||
1029 | * this loop even if all the digits are zero. | - | ||||||||||||||||||
1030 | */ | - | ||||||||||||||||||
1031 | while (*--p == '0')
| 0 | ||||||||||||||||||
1032 | continue; never executed: continue; | 0 | ||||||||||||||||||
1033 | if (*p != '.')
| 0 | ||||||||||||||||||
1034 | ++p; never executed: ++p; | 0 | ||||||||||||||||||
1035 | } never executed: end of block | 0 | ||||||||||||||||||
1036 | *p++ = 'Z'; | - | ||||||||||||||||||
1037 | *p++ = '\0'; | - | ||||||||||||||||||
1038 | - | |||||||||||||||||||
1039 | if (asn1_time == NULL
| 0 | ||||||||||||||||||
1040 | && (asn1_time = ASN1_GENERALIZEDTIME_new()) == NULL)
| 0 | ||||||||||||||||||
1041 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
1042 | if (!ASN1_GENERALIZEDTIME_set_string(asn1_time, genTime_str)) {
| 0 | ||||||||||||||||||
1043 | ASN1_GENERALIZEDTIME_free(asn1_time); | - | ||||||||||||||||||
1044 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
1045 | } | - | ||||||||||||||||||
1046 | return asn1_time; never executed: return asn1_time; | 0 | ||||||||||||||||||
1047 | - | |||||||||||||||||||
1048 | err: | - | ||||||||||||||||||
1049 | TSerr(TS_F_TS_RESP_SET_GENTIME_WITH_PRECISION, TS_R_COULD_NOT_SET_TIME); | - | ||||||||||||||||||
1050 | return NULL; never executed: return ((void *)0) ; | 0 | ||||||||||||||||||
1051 | } | - | ||||||||||||||||||
1052 | - | |||||||||||||||||||
1053 | int TS_RESP_CTX_set_ess_cert_id_digest(TS_RESP_CTX *ctx, const EVP_MD *md) | - | ||||||||||||||||||
1054 | { | - | ||||||||||||||||||
1055 | ctx->ess_cert_id_digest = md; | - | ||||||||||||||||||
1056 | return 1; never executed: return 1; | 0 | ||||||||||||||||||
1057 | } | - | ||||||||||||||||||
Source code | Switch to Preprocessed file |