| GCC Code Coverage Report | |||||||||||||||||||||
        
  | 
    |||||||||||||||||||||
| Line | Branch | Exec | Source | 
1  | 
    /* $OpenBSD: ts_rsp_sign.c,v 1.21 2017/01/29 17:49:23 beck Exp $ */  | 
    ||
2  | 
    /* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL  | 
    ||
3  | 
    * project 2002.  | 
    ||
4  | 
    */  | 
    ||
5  | 
    /* ====================================================================  | 
    ||
6  | 
    * Copyright (c) 2006 The OpenSSL Project. All rights reserved.  | 
    ||
7  | 
    *  | 
    ||
8  | 
    * Redistribution and use in source and binary forms, with or without  | 
    ||
9  | 
    * modification, are permitted provided that the following conditions  | 
    ||
10  | 
    * are met:  | 
    ||
11  | 
    *  | 
    ||
12  | 
    * 1. Redistributions of source code must retain the above copyright  | 
    ||
13  | 
    * notice, this list of conditions and the following disclaimer.  | 
    ||
14  | 
    *  | 
    ||
15  | 
    * 2. Redistributions in binary form must reproduce the above copyright  | 
    ||
16  | 
    * notice, this list of conditions and the following disclaimer in  | 
    ||
17  | 
    * the documentation and/or other materials provided with the  | 
    ||
18  | 
    * distribution.  | 
    ||
19  | 
    *  | 
    ||
20  | 
    * 3. All advertising materials mentioning features or use of this  | 
    ||
21  | 
    * software must display the following acknowledgment:  | 
    ||
22  | 
    * "This product includes software developed by the OpenSSL Project  | 
    ||
23  | 
    * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"  | 
    ||
24  | 
    *  | 
    ||
25  | 
    * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to  | 
    ||
26  | 
    * endorse or promote products derived from this software without  | 
    ||
27  | 
    * prior written permission. For written permission, please contact  | 
    ||
28  | 
    * licensing@OpenSSL.org.  | 
    ||
29  | 
    *  | 
    ||
30  | 
    * 5. Products derived from this software may not be called "OpenSSL"  | 
    ||
31  | 
    * nor may "OpenSSL" appear in their names without prior written  | 
    ||
32  | 
    * permission of the OpenSSL Project.  | 
    ||
33  | 
    *  | 
    ||
34  | 
    * 6. Redistributions of any form whatsoever must retain the following  | 
    ||
35  | 
    * acknowledgment:  | 
    ||
36  | 
    * "This product includes software developed by the OpenSSL Project  | 
    ||
37  | 
    * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"  | 
    ||
38  | 
    *  | 
    ||
39  | 
    * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY  | 
    ||
40  | 
    * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE  | 
    ||
41  | 
    * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR  | 
    ||
42  | 
    * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR  | 
    ||
43  | 
    * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,  | 
    ||
44  | 
    * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT  | 
    ||
45  | 
    * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;  | 
    ||
46  | 
    * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)  | 
    ||
47  | 
    * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,  | 
    ||
48  | 
    * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)  | 
    ||
49  | 
    * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED  | 
    ||
50  | 
    * OF THE POSSIBILITY OF SUCH DAMAGE.  | 
    ||
51  | 
    * ====================================================================  | 
    ||
52  | 
    *  | 
    ||
53  | 
    * This product includes cryptographic software written by Eric Young  | 
    ||
54  | 
    * (eay@cryptsoft.com). This product includes software written by Tim  | 
    ||
55  | 
    * Hudson (tjh@cryptsoft.com).  | 
    ||
56  | 
    *  | 
    ||
57  | 
    */  | 
    ||
58  | 
    |||
59  | 
    #include <sys/time.h>  | 
    ||
60  | 
    |||
61  | 
    #include <string.h>  | 
    ||
62  | 
    |||
63  | 
    #include <openssl/err.h>  | 
    ||
64  | 
    #include <openssl/objects.h>  | 
    ||
65  | 
    #include <openssl/pkcs7.h>  | 
    ||
66  | 
    #include <openssl/ts.h>  | 
    ||
67  | 
    |||
68  | 
    /* Private function declarations. */  | 
    ||
69  | 
    |||
70  | 
    static ASN1_INTEGER *def_serial_cb(struct TS_resp_ctx *, void *);  | 
    ||
71  | 
    static int def_time_cb(struct TS_resp_ctx *, void *, time_t *sec, long *usec);  | 
    ||
72  | 
    static int def_extension_cb(struct TS_resp_ctx *, X509_EXTENSION *, void *);  | 
    ||
73  | 
    |||
74  | 
    static void TS_RESP_CTX_init(TS_RESP_CTX *ctx);  | 
    ||
75  | 
    static void TS_RESP_CTX_cleanup(TS_RESP_CTX *ctx);  | 
    ||
76  | 
    static int TS_RESP_check_request(TS_RESP_CTX *ctx);  | 
    ||
77  | 
    static ASN1_OBJECT *TS_RESP_get_policy(TS_RESP_CTX *ctx);  | 
    ||
78  | 
    static TS_TST_INFO *TS_RESP_create_tst_info(TS_RESP_CTX *ctx,  | 
    ||
79  | 
    ASN1_OBJECT *policy);  | 
    ||
80  | 
    static int TS_RESP_process_extensions(TS_RESP_CTX *ctx);  | 
    ||
81  | 
    static int TS_RESP_sign(TS_RESP_CTX *ctx);  | 
    ||
82  | 
    |||
83  | 
    static ESS_SIGNING_CERT *ESS_SIGNING_CERT_new_init(X509 *signcert,  | 
    ||
84  | 
    STACK_OF(X509) *certs);  | 
    ||
85  | 
    static ESS_CERT_ID *ESS_CERT_ID_new_init(X509 *cert, int issuer_needed);  | 
    ||
86  | 
    static int TS_TST_INFO_content_new(PKCS7 *p7);  | 
    ||
87  | 
    static int ESS_add_signing_cert(PKCS7_SIGNER_INFO *si, ESS_SIGNING_CERT *sc);  | 
    ||
88  | 
    |||
89  | 
    static ASN1_GENERALIZEDTIME *TS_RESP_set_genTime_with_precision(  | 
    ||
90  | 
    ASN1_GENERALIZEDTIME *, time_t, long, unsigned);  | 
    ||
91  | 
    |||
92  | 
    /* Default callbacks for response generation. */  | 
    ||
93  | 
    |||
94  | 
    static ASN1_INTEGER *  | 
    ||
95  | 
    def_serial_cb(struct TS_resp_ctx *ctx, void *data)  | 
    ||
96  | 
    { | 
    ||
97  | 
    ASN1_INTEGER *serial = ASN1_INTEGER_new();  | 
    ||
98  | 
    |||
99  | 
    if (!serial)  | 
    ||
100  | 
    goto err;  | 
    ||
101  | 
    if (!ASN1_INTEGER_set(serial, 1))  | 
    ||
102  | 
    goto err;  | 
    ||
103  | 
    return serial;  | 
    ||
104  | 
    |||
105  | 
    err:  | 
    ||
106  | 
    TSerror(ERR_R_MALLOC_FAILURE);  | 
    ||
107  | 
    TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,  | 
    ||
108  | 
    "Error during serial number generation.");  | 
    ||
109  | 
    return NULL;  | 
    ||
110  | 
    }  | 
    ||
111  | 
    |||
112  | 
    /* Use the gettimeofday function call. */  | 
    ||
113  | 
    static int  | 
    ||
114  | 
    def_time_cb(struct TS_resp_ctx *ctx, void *data, time_t *sec, long *usec)  | 
    ||
115  | 
    { | 
    ||
116  | 
    4  | 
    struct timeval tv;  | 
    |
117  | 
    |||
118  | 
    ✗✓ | 2  | 
    	if (gettimeofday(&tv, NULL) != 0) { | 
    
119  | 
    TSerror(TS_R_TIME_SYSCALL_ERROR);  | 
    ||
120  | 
    TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,  | 
    ||
121  | 
    "Time is not available.");  | 
    ||
122  | 
    TS_RESP_CTX_add_failure_info(ctx, TS_INFO_TIME_NOT_AVAILABLE);  | 
    ||
123  | 
    return 0;  | 
    ||
124  | 
    }  | 
    ||
125  | 
    /* Return time to caller. */  | 
    ||
126  | 
    2  | 
    *sec = tv.tv_sec;  | 
    |
127  | 
    2  | 
    *usec = tv.tv_usec;  | 
    |
128  | 
    |||
129  | 
    2  | 
    return 1;  | 
    |
130  | 
    2  | 
    }  | 
    |
131  | 
    |||
132  | 
    static int  | 
    ||
133  | 
    def_extension_cb(struct TS_resp_ctx *ctx, X509_EXTENSION *ext, void *data)  | 
    ||
134  | 
    { | 
    ||
135  | 
    /* No extensions are processed here. */  | 
    ||
136  | 
    TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,  | 
    ||
137  | 
    "Unsupported extension.");  | 
    ||
138  | 
    TS_RESP_CTX_add_failure_info(ctx, TS_INFO_UNACCEPTED_EXTENSION);  | 
    ||
139  | 
    return 0;  | 
    ||
140  | 
    }  | 
    ||
141  | 
    |||
142  | 
    /* TS_RESP_CTX management functions. */  | 
    ||
143  | 
    |||
144  | 
    TS_RESP_CTX *  | 
    ||
145  | 
    TS_RESP_CTX_new(void)  | 
    ||
146  | 
    { | 
    ||
147  | 
    TS_RESP_CTX *ctx;  | 
    ||
148  | 
    |||
149  | 
    ✗✓ | 4  | 
    	if (!(ctx = calloc(1, sizeof(TS_RESP_CTX)))) { | 
    
150  | 
    TSerror(ERR_R_MALLOC_FAILURE);  | 
    ||
151  | 
    return NULL;  | 
    ||
152  | 
    }  | 
    ||
153  | 
    |||
154  | 
    /* Setting default callbacks. */  | 
    ||
155  | 
    2  | 
    ctx->serial_cb = def_serial_cb;  | 
    |
156  | 
    2  | 
    ctx->time_cb = def_time_cb;  | 
    |
157  | 
    2  | 
    ctx->extension_cb = def_extension_cb;  | 
    |
158  | 
    |||
159  | 
    2  | 
    return ctx;  | 
    |
160  | 
    2  | 
    }  | 
    |
161  | 
    |||
162  | 
    void  | 
    ||
163  | 
    TS_RESP_CTX_free(TS_RESP_CTX *ctx)  | 
    ||
164  | 
    { | 
    ||
165  | 
    ✓✗ | 4  | 
    if (!ctx)  | 
    
166  | 
    return;  | 
    ||
167  | 
    |||
168  | 
    2  | 
    X509_free(ctx->signer_cert);  | 
    |
169  | 
    2  | 
    EVP_PKEY_free(ctx->signer_key);  | 
    |
170  | 
    2  | 
    sk_X509_pop_free(ctx->certs, X509_free);  | 
    |
171  | 
    2  | 
    sk_ASN1_OBJECT_pop_free(ctx->policies, ASN1_OBJECT_free);  | 
    |
172  | 
    2  | 
    ASN1_OBJECT_free(ctx->default_policy);  | 
    |
173  | 
    2  | 
    sk_EVP_MD_free(ctx->mds); /* No EVP_MD_free method exists. */  | 
    |
174  | 
    2  | 
    ASN1_INTEGER_free(ctx->seconds);  | 
    |
175  | 
    2  | 
    ASN1_INTEGER_free(ctx->millis);  | 
    |
176  | 
    2  | 
    ASN1_INTEGER_free(ctx->micros);  | 
    |
177  | 
    2  | 
    free(ctx);  | 
    |
178  | 
    4  | 
    }  | 
    |
179  | 
    |||
180  | 
    int  | 
    ||
181  | 
    TS_RESP_CTX_set_signer_cert(TS_RESP_CTX *ctx, X509 *signer)  | 
    ||
182  | 
    { | 
    ||
183  | 
    ✗✓ | 4  | 
    	if (X509_check_purpose(signer, X509_PURPOSE_TIMESTAMP_SIGN, 0) != 1) { | 
    
184  | 
    TSerror(TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE);  | 
    ||
185  | 
    return 0;  | 
    ||
186  | 
    }  | 
    ||
187  | 
    2  | 
    X509_free(ctx->signer_cert);  | 
    |
188  | 
    2  | 
    ctx->signer_cert = signer;  | 
    |
189  | 
    2  | 
    CRYPTO_add(&ctx->signer_cert->references, +1, CRYPTO_LOCK_X509);  | 
    |
190  | 
    2  | 
    return 1;  | 
    |
191  | 
    2  | 
    }  | 
    |
192  | 
    |||
193  | 
    int  | 
    ||
194  | 
    TS_RESP_CTX_set_signer_key(TS_RESP_CTX *ctx, EVP_PKEY *key)  | 
    ||
195  | 
    { | 
    ||
196  | 
    4  | 
    EVP_PKEY_free(ctx->signer_key);  | 
    |
197  | 
    2  | 
    ctx->signer_key = key;  | 
    |
198  | 
    2  | 
    CRYPTO_add(&ctx->signer_key->references, +1, CRYPTO_LOCK_EVP_PKEY);  | 
    |
199  | 
    |||
200  | 
    2  | 
    return 1;  | 
    |
201  | 
    }  | 
    ||
202  | 
    |||
203  | 
    int  | 
    ||
204  | 
    TS_RESP_CTX_set_def_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *def_policy)  | 
    ||
205  | 
    { | 
    ||
206  | 
    ✗✓ | 4  | 
    if (ctx->default_policy)  | 
    
207  | 
    ASN1_OBJECT_free(ctx->default_policy);  | 
    ||
208  | 
    ✓✗ | 2  | 
    if (!(ctx->default_policy = OBJ_dup(def_policy)))  | 
    
209  | 
    goto err;  | 
    ||
210  | 
    2  | 
    return 1;  | 
    |
211  | 
    |||
212  | 
    err:  | 
    ||
213  | 
    TSerror(ERR_R_MALLOC_FAILURE);  | 
    ||
214  | 
    return 0;  | 
    ||
215  | 
    2  | 
    }  | 
    |
216  | 
    |||
217  | 
    int  | 
    ||
218  | 
    TS_RESP_CTX_set_certs(TS_RESP_CTX *ctx, STACK_OF(X509) *certs)  | 
    ||
219  | 
    { | 
    ||
220  | 
    int i;  | 
    ||
221  | 
    |||
222  | 
    ✗✓ | 4  | 
    	if (ctx->certs) { | 
    
223  | 
    sk_X509_pop_free(ctx->certs, X509_free);  | 
    ||
224  | 
    ctx->certs = NULL;  | 
    ||
225  | 
    }  | 
    ||
226  | 
    ✗✓ | 2  | 
    if (!certs)  | 
    
227  | 
    return 1;  | 
    ||
228  | 
    ✗✓ | 2  | 
    	if (!(ctx->certs = sk_X509_dup(certs))) { | 
    
229  | 
    TSerror(ERR_R_MALLOC_FAILURE);  | 
    ||
230  | 
    return 0;  | 
    ||
231  | 
    }  | 
    ||
232  | 
    ✓✓ | 8  | 
    	for (i = 0; i < sk_X509_num(ctx->certs); ++i) { | 
    
233  | 
    2  | 
    X509 *cert = sk_X509_value(ctx->certs, i);  | 
    |
234  | 
    2  | 
    CRYPTO_add(&cert->references, +1, CRYPTO_LOCK_X509);  | 
    |
235  | 
    }  | 
    ||
236  | 
    |||
237  | 
    2  | 
    return 1;  | 
    |
238  | 
    2  | 
    }  | 
    |
239  | 
    |||
240  | 
    int  | 
    ||
241  | 
    TS_RESP_CTX_add_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *policy)  | 
    ||
242  | 
    { | 
    ||
243  | 
    ASN1_OBJECT *copy = NULL;  | 
    ||
244  | 
    |||
245  | 
    /* Create new policy stack if necessary. */  | 
    ||
246  | 
    ✓✓✓✗ | 
    10  | 
    if (!ctx->policies && !(ctx->policies = sk_ASN1_OBJECT_new_null()))  | 
    
247  | 
    goto err;  | 
    ||
248  | 
    ✓✗ | 4  | 
    if (!(copy = OBJ_dup(policy)))  | 
    
249  | 
    goto err;  | 
    ||
250  | 
    ✓✗ | 4  | 
    if (!sk_ASN1_OBJECT_push(ctx->policies, copy))  | 
    
251  | 
    goto err;  | 
    ||
252  | 
    |||
253  | 
    4  | 
    return 1;  | 
    |
254  | 
    |||
255  | 
    err:  | 
    ||
256  | 
    TSerror(ERR_R_MALLOC_FAILURE);  | 
    ||
257  | 
    ASN1_OBJECT_free(copy);  | 
    ||
258  | 
    return 0;  | 
    ||
259  | 
    4  | 
    }  | 
    |
260  | 
    |||
261  | 
    int  | 
    ||
262  | 
    TS_RESP_CTX_add_md(TS_RESP_CTX *ctx, const EVP_MD *md)  | 
    ||
263  | 
    { | 
    ||
264  | 
    /* Create new md stack if necessary. */  | 
    ||
265  | 
    ✓✓✓✗ | 
    18  | 
    if (!ctx->mds && !(ctx->mds = sk_EVP_MD_new_null()))  | 
    
266  | 
    goto err;  | 
    ||
267  | 
    /* Add the shared md, no copy needed. */  | 
    ||
268  | 
    ✓✗ | 8  | 
    if (!sk_EVP_MD_push(ctx->mds, (EVP_MD *)md))  | 
    
269  | 
    goto err;  | 
    ||
270  | 
    |||
271  | 
    8  | 
    return 1;  | 
    |
272  | 
    |||
273  | 
    err:  | 
    ||
274  | 
    TSerror(ERR_R_MALLOC_FAILURE);  | 
    ||
275  | 
    return 0;  | 
    ||
276  | 
    8  | 
    }  | 
    |
277  | 
    |||
278  | 
    #define TS_RESP_CTX_accuracy_free(ctx) \  | 
    ||
279  | 
    ASN1_INTEGER_free(ctx->seconds); \  | 
    ||
280  | 
    ctx->seconds = NULL; \  | 
    ||
281  | 
    ASN1_INTEGER_free(ctx->millis); \  | 
    ||
282  | 
    ctx->millis = NULL; \  | 
    ||
283  | 
    ASN1_INTEGER_free(ctx->micros); \  | 
    ||
284  | 
    ctx->micros = NULL;  | 
    ||
285  | 
    |||
286  | 
    int  | 
    ||
287  | 
    TS_RESP_CTX_set_accuracy(TS_RESP_CTX *ctx, int secs, int millis, int micros)  | 
    ||
288  | 
    { | 
    ||
289  | 
    4  | 
    TS_RESP_CTX_accuracy_free(ctx);  | 
    |
290  | 
    ✗✓✗✗ ✗✗  | 
    2  | 
    if (secs && (!(ctx->seconds = ASN1_INTEGER_new()) ||  | 
    
291  | 
    !ASN1_INTEGER_set(ctx->seconds, secs)))  | 
    ||
292  | 
    goto err;  | 
    ||
293  | 
    ✗✓✗✗ ✗✗  | 
    2  | 
    if (millis && (!(ctx->millis = ASN1_INTEGER_new()) ||  | 
    
294  | 
    !ASN1_INTEGER_set(ctx->millis, millis)))  | 
    ||
295  | 
    goto err;  | 
    ||
296  | 
    ✗✓✗✗ ✗✗  | 
    2  | 
    if (micros && (!(ctx->micros = ASN1_INTEGER_new()) ||  | 
    
297  | 
    !ASN1_INTEGER_set(ctx->micros, micros)))  | 
    ||
298  | 
    goto err;  | 
    ||
299  | 
    |||
300  | 
    2  | 
    return 1;  | 
    |
301  | 
    |||
302  | 
    err:  | 
    ||
303  | 
    TS_RESP_CTX_accuracy_free(ctx);  | 
    ||
304  | 
    TSerror(ERR_R_MALLOC_FAILURE);  | 
    ||
305  | 
    return 0;  | 
    ||
306  | 
    2  | 
    }  | 
    |
307  | 
    |||
308  | 
    void  | 
    ||
309  | 
    TS_RESP_CTX_add_flags(TS_RESP_CTX *ctx, int flags)  | 
    ||
310  | 
    { | 
    ||
311  | 
    ctx->flags |= flags;  | 
    ||
312  | 
    }  | 
    ||
313  | 
    |||
314  | 
    void  | 
    ||
315  | 
    TS_RESP_CTX_set_serial_cb(TS_RESP_CTX *ctx, TS_serial_cb cb, void *data)  | 
    ||
316  | 
    { | 
    ||
317  | 
    4  | 
    ctx->serial_cb = cb;  | 
    |
318  | 
    2  | 
    ctx->serial_cb_data = data;  | 
    |
319  | 
    2  | 
    }  | 
    |
320  | 
    |||
321  | 
    void  | 
    ||
322  | 
    TS_RESP_CTX_set_extension_cb(TS_RESP_CTX *ctx, TS_extension_cb cb, void *data)  | 
    ||
323  | 
    { | 
    ||
324  | 
    ctx->extension_cb = cb;  | 
    ||
325  | 
    ctx->extension_cb_data = data;  | 
    ||
326  | 
    }  | 
    ||
327  | 
    |||
328  | 
    int  | 
    ||
329  | 
    TS_RESP_CTX_set_status_info(TS_RESP_CTX *ctx, int status, const char *text)  | 
    ||
330  | 
    { | 
    ||
331  | 
    TS_STATUS_INFO *si = NULL;  | 
    ||
332  | 
    ASN1_UTF8STRING *utf8_text = NULL;  | 
    ||
333  | 
    int ret = 0;  | 
    ||
334  | 
    |||
335  | 
    ✓✗ | 4  | 
    if (!(si = TS_STATUS_INFO_new()))  | 
    
336  | 
    goto err;  | 
    ||
337  | 
    ✓✗ | 2  | 
    if (!ASN1_INTEGER_set(si->status, status))  | 
    
338  | 
    goto err;  | 
    ||
339  | 
    ✗✓ | 2  | 
    	if (text) { | 
    
340  | 
    if (!(utf8_text = ASN1_UTF8STRING_new()) ||  | 
    ||
341  | 
    !ASN1_STRING_set(utf8_text, text, strlen(text)))  | 
    ||
342  | 
    goto err;  | 
    ||
343  | 
    if (!si->text && !(si->text = sk_ASN1_UTF8STRING_new_null()))  | 
    ||
344  | 
    goto err;  | 
    ||
345  | 
    if (!sk_ASN1_UTF8STRING_push(si->text, utf8_text))  | 
    ||
346  | 
    goto err;  | 
    ||
347  | 
    utf8_text = NULL; /* Ownership is lost. */  | 
    ||
348  | 
    }  | 
    ||
349  | 
    ✓✗ | 2  | 
    if (!TS_RESP_set_status_info(ctx->response, si))  | 
    
350  | 
    goto err;  | 
    ||
351  | 
    2  | 
    ret = 1;  | 
    |
352  | 
    |||
353  | 
    err:  | 
    ||
354  | 
    ✗✓ | 2  | 
    if (!ret)  | 
    
355  | 
    TSerror(ERR_R_MALLOC_FAILURE);  | 
    ||
356  | 
    2  | 
    TS_STATUS_INFO_free(si);  | 
    |
357  | 
    2  | 
    ASN1_UTF8STRING_free(utf8_text);  | 
    |
358  | 
    2  | 
    return ret;  | 
    |
359  | 
    }  | 
    ||
360  | 
    |||
361  | 
    int  | 
    ||
362  | 
    TS_RESP_CTX_set_status_info_cond(TS_RESP_CTX *ctx, int status, const char *text)  | 
    ||
363  | 
    { | 
    ||
364  | 
    int ret = 1;  | 
    ||
365  | 
    TS_STATUS_INFO *si = TS_RESP_get_status_info(ctx->response);  | 
    ||
366  | 
    |||
367  | 
    	if (ASN1_INTEGER_get(si->status) == TS_STATUS_GRANTED) { | 
    ||
368  | 
    /* Status has not been set, set it now. */  | 
    ||
369  | 
    ret = TS_RESP_CTX_set_status_info(ctx, status, text);  | 
    ||
370  | 
    }  | 
    ||
371  | 
    return ret;  | 
    ||
372  | 
    }  | 
    ||
373  | 
    |||
374  | 
    int  | 
    ||
375  | 
    TS_RESP_CTX_add_failure_info(TS_RESP_CTX *ctx, int failure)  | 
    ||
376  | 
    { | 
    ||
377  | 
    TS_STATUS_INFO *si = TS_RESP_get_status_info(ctx->response);  | 
    ||
378  | 
    |||
379  | 
    if (!si->failure_info && !(si->failure_info = ASN1_BIT_STRING_new()))  | 
    ||
380  | 
    goto err;  | 
    ||
381  | 
    if (!ASN1_BIT_STRING_set_bit(si->failure_info, failure, 1))  | 
    ||
382  | 
    goto err;  | 
    ||
383  | 
    return 1;  | 
    ||
384  | 
    |||
385  | 
    err:  | 
    ||
386  | 
    TSerror(ERR_R_MALLOC_FAILURE);  | 
    ||
387  | 
    return 0;  | 
    ||
388  | 
    }  | 
    ||
389  | 
    |||
390  | 
    TS_REQ *  | 
    ||
391  | 
    TS_RESP_CTX_get_request(TS_RESP_CTX *ctx)  | 
    ||
392  | 
    { | 
    ||
393  | 
    return ctx->request;  | 
    ||
394  | 
    }  | 
    ||
395  | 
    |||
396  | 
    TS_TST_INFO *  | 
    ||
397  | 
    TS_RESP_CTX_get_tst_info(TS_RESP_CTX *ctx)  | 
    ||
398  | 
    { | 
    ||
399  | 
    return ctx->tst_info;  | 
    ||
400  | 
    }  | 
    ||
401  | 
    |||
402  | 
    int  | 
    ||
403  | 
    TS_RESP_CTX_set_clock_precision_digits(TS_RESP_CTX *ctx, unsigned precision)  | 
    ||
404  | 
    { | 
    ||
405  | 
    ✗✓ | 4  | 
    if (precision > TS_MAX_CLOCK_PRECISION_DIGITS)  | 
    
406  | 
    return 0;  | 
    ||
407  | 
    2  | 
    ctx->clock_precision_digits = precision;  | 
    |
408  | 
    2  | 
    return 1;  | 
    |
409  | 
    2  | 
    }  | 
    |
410  | 
    |||
411  | 
    /* Main entry method of the response generation. */  | 
    ||
412  | 
    TS_RESP *  | 
    ||
413  | 
    TS_RESP_create_response(TS_RESP_CTX *ctx, BIO *req_bio)  | 
    ||
414  | 
    { | 
    ||
415  | 
    ASN1_OBJECT *policy;  | 
    ||
416  | 
    TS_RESP *response;  | 
    ||
417  | 
    int result = 0;  | 
    ||
418  | 
    |||
419  | 
    4  | 
    TS_RESP_CTX_init(ctx);  | 
    |
420  | 
    |||
421  | 
    /* Creating the response object. */  | 
    ||
422  | 
    ✗✓ | 2  | 
    	if (!(ctx->response = TS_RESP_new())) { | 
    
423  | 
    TSerror(ERR_R_MALLOC_FAILURE);  | 
    ||
424  | 
    goto end;  | 
    ||
425  | 
    }  | 
    ||
426  | 
    |||
427  | 
    /* Parsing DER request. */  | 
    ||
428  | 
    ✗✓ | 2  | 
    	if (!(ctx->request = d2i_TS_REQ_bio(req_bio, NULL))) { | 
    
429  | 
    TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,  | 
    ||
430  | 
    "Bad request format or "  | 
    ||
431  | 
    "system error.");  | 
    ||
432  | 
    TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_DATA_FORMAT);  | 
    ||
433  | 
    goto end;  | 
    ||
434  | 
    }  | 
    ||
435  | 
    |||
436  | 
    /* Setting default status info. */  | 
    ||
437  | 
    ✓✗ | 2  | 
    if (!TS_RESP_CTX_set_status_info(ctx, TS_STATUS_GRANTED, NULL))  | 
    
438  | 
    goto end;  | 
    ||
439  | 
    |||
440  | 
    /* Checking the request format. */  | 
    ||
441  | 
    ✓✗ | 2  | 
    if (!TS_RESP_check_request(ctx))  | 
    
442  | 
    goto end;  | 
    ||
443  | 
    |||
444  | 
    /* Checking acceptable policies. */  | 
    ||
445  | 
    ✓✗ | 2  | 
    if (!(policy = TS_RESP_get_policy(ctx)))  | 
    
446  | 
    goto end;  | 
    ||
447  | 
    |||
448  | 
    /* Creating the TS_TST_INFO object. */  | 
    ||
449  | 
    ✓✗ | 2  | 
    if (!(ctx->tst_info = TS_RESP_create_tst_info(ctx, policy)))  | 
    
450  | 
    goto end;  | 
    ||
451  | 
    |||
452  | 
    /* Processing extensions. */  | 
    ||
453  | 
    ✓✗ | 2  | 
    if (!TS_RESP_process_extensions(ctx))  | 
    
454  | 
    goto end;  | 
    ||
455  | 
    |||
456  | 
    /* Generating the signature. */  | 
    ||
457  | 
    ✓✗ | 2  | 
    if (!TS_RESP_sign(ctx))  | 
    
458  | 
    goto end;  | 
    ||
459  | 
    |||
460  | 
    /* Everything was successful. */  | 
    ||
461  | 
    2  | 
    result = 1;  | 
    |
462  | 
    |||
463  | 
    end:  | 
    ||
464  | 
    ✗✓ | 2  | 
    	if (!result) { | 
    
465  | 
    TSerror(TS_R_RESPONSE_SETUP_ERROR);  | 
    ||
466  | 
    		if (ctx->response != NULL) { | 
    ||
467  | 
    if (TS_RESP_CTX_set_status_info_cond(ctx,  | 
    ||
468  | 
    TS_STATUS_REJECTION, "Error during response "  | 
    ||
469  | 
    			    "generation.") == 0) { | 
    ||
470  | 
    TS_RESP_free(ctx->response);  | 
    ||
471  | 
    ctx->response = NULL;  | 
    ||
472  | 
    }  | 
    ||
473  | 
    }  | 
    ||
474  | 
    }  | 
    ||
475  | 
    2  | 
    response = ctx->response;  | 
    |
476  | 
    2  | 
    ctx->response = NULL; /* Ownership will be returned to caller. */  | 
    |
477  | 
    2  | 
    TS_RESP_CTX_cleanup(ctx);  | 
    |
478  | 
    2  | 
    return response;  | 
    |
479  | 
    }  | 
    ||
480  | 
    |||
481  | 
    /* Initializes the variable part of the context. */  | 
    ||
482  | 
    static void  | 
    ||
483  | 
    TS_RESP_CTX_init(TS_RESP_CTX *ctx)  | 
    ||
484  | 
    { | 
    ||
485  | 
    4  | 
    ctx->request = NULL;  | 
    |
486  | 
    2  | 
    ctx->response = NULL;  | 
    |
487  | 
    2  | 
    ctx->tst_info = NULL;  | 
    |
488  | 
    2  | 
    }  | 
    |
489  | 
    |||
490  | 
    /* Cleans up the variable part of the context. */  | 
    ||
491  | 
    static void  | 
    ||
492  | 
    TS_RESP_CTX_cleanup(TS_RESP_CTX *ctx)  | 
    ||
493  | 
    { | 
    ||
494  | 
    4  | 
    TS_REQ_free(ctx->request);  | 
    |
495  | 
    2  | 
    ctx->request = NULL;  | 
    |
496  | 
    2  | 
    TS_RESP_free(ctx->response);  | 
    |
497  | 
    2  | 
    ctx->response = NULL;  | 
    |
498  | 
    2  | 
    TS_TST_INFO_free(ctx->tst_info);  | 
    |
499  | 
    2  | 
    ctx->tst_info = NULL;  | 
    |
500  | 
    2  | 
    }  | 
    |
501  | 
    |||
502  | 
    /* Checks the format and content of the request. */  | 
    ||
503  | 
    static int  | 
    ||
504  | 
    TS_RESP_check_request(TS_RESP_CTX *ctx)  | 
    ||
505  | 
    { | 
    ||
506  | 
    4  | 
    TS_REQ *request = ctx->request;  | 
    |
507  | 
    TS_MSG_IMPRINT *msg_imprint;  | 
    ||
508  | 
    X509_ALGOR *md_alg;  | 
    ||
509  | 
    int md_alg_id;  | 
    ||
510  | 
    const ASN1_OCTET_STRING *digest;  | 
    ||
511  | 
    EVP_MD *md = NULL;  | 
    ||
512  | 
    int i;  | 
    ||
513  | 
    |||
514  | 
    /* Checking request version. */  | 
    ||
515  | 
    ✗✓ | 2  | 
    	if (TS_REQ_get_version(request) != 1) { | 
    
516  | 
    TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,  | 
    ||
517  | 
    "Bad request version.");  | 
    ||
518  | 
    TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_REQUEST);  | 
    ||
519  | 
    return 0;  | 
    ||
520  | 
    }  | 
    ||
521  | 
    |||
522  | 
    /* Checking message digest algorithm. */  | 
    ||
523  | 
    2  | 
    msg_imprint = TS_REQ_get_msg_imprint(request);  | 
    |
524  | 
    2  | 
    md_alg = TS_MSG_IMPRINT_get_algo(msg_imprint);  | 
    |
525  | 
    2  | 
    md_alg_id = OBJ_obj2nid(md_alg->algorithm);  | 
    |
526  | 
    ✓✓✓✗ | 
    10  | 
    	for (i = 0; !md && i < sk_EVP_MD_num(ctx->mds); ++i) { | 
    
527  | 
    2  | 
    EVP_MD *current_md = sk_EVP_MD_value(ctx->mds, i);  | 
    |
528  | 
    ✓✗ | 2  | 
    if (md_alg_id == EVP_MD_type(current_md))  | 
    
529  | 
    2  | 
    md = current_md;  | 
    |
530  | 
    }  | 
    ||
531  | 
    ✗✓ | 2  | 
    	if (!md) { | 
    
532  | 
    TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,  | 
    ||
533  | 
    "Message digest algorithm is "  | 
    ||
534  | 
    "not supported.");  | 
    ||
535  | 
    TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_ALG);  | 
    ||
536  | 
    return 0;  | 
    ||
537  | 
    }  | 
    ||
538  | 
    |||
539  | 
    /* No message digest takes parameter. */  | 
    ||
540  | 
    ✓✗✗✓ | 
    4  | 
    if (md_alg->parameter &&  | 
    
541  | 
    2  | 
    	    ASN1_TYPE_get(md_alg->parameter) != V_ASN1_NULL) { | 
    |
542  | 
    TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,  | 
    ||
543  | 
    "Superfluous message digest "  | 
    ||
544  | 
    "parameter.");  | 
    ||
545  | 
    TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_ALG);  | 
    ||
546  | 
    return 0;  | 
    ||
547  | 
    }  | 
    ||
548  | 
    /* Checking message digest size. */  | 
    ||
549  | 
    2  | 
    digest = TS_MSG_IMPRINT_get_msg(msg_imprint);  | 
    |
550  | 
    ✗✓ | 2  | 
    	if (digest->length != EVP_MD_size(md)) { | 
    
551  | 
    TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,  | 
    ||
552  | 
    "Bad message digest.");  | 
    ||
553  | 
    TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_DATA_FORMAT);  | 
    ||
554  | 
    return 0;  | 
    ||
555  | 
    }  | 
    ||
556  | 
    |||
557  | 
    2  | 
    return 1;  | 
    |
558  | 
    2  | 
    }  | 
    |
559  | 
    |||
560  | 
    /* Returns the TSA policy based on the requested and acceptable policies. */  | 
    ||
561  | 
    static ASN1_OBJECT *  | 
    ||
562  | 
    TS_RESP_get_policy(TS_RESP_CTX *ctx)  | 
    ||
563  | 
    { | 
    ||
564  | 
    4  | 
    ASN1_OBJECT *requested = TS_REQ_get_policy_id(ctx->request);  | 
    |
565  | 
    ASN1_OBJECT *policy = NULL;  | 
    ||
566  | 
    int i;  | 
    ||
567  | 
    |||
568  | 
    ✗✓ | 2  | 
    	if (ctx->default_policy == NULL) { | 
    
569  | 
    TSerror(TS_R_INVALID_NULL_POINTER);  | 
    ||
570  | 
    return NULL;  | 
    ||
571  | 
    }  | 
    ||
572  | 
    /* Return the default policy if none is requested or the default is  | 
    ||
573  | 
    requested. */  | 
    ||
574  | 
    ✗✓✗✗ | 
    2  | 
    if (!requested || !OBJ_cmp(requested, ctx->default_policy))  | 
    
575  | 
    2  | 
    policy = ctx->default_policy;  | 
    |
576  | 
    |||
577  | 
    /* Check if the policy is acceptable. */  | 
    ||
578  | 
    ✗✓✗✗ | 
    4  | 
    	for (i = 0; !policy && i < sk_ASN1_OBJECT_num(ctx->policies); ++i) { | 
    
579  | 
    ASN1_OBJECT *current = sk_ASN1_OBJECT_value(ctx->policies, i);  | 
    ||
580  | 
    if (!OBJ_cmp(requested, current))  | 
    ||
581  | 
    policy = current;  | 
    ||
582  | 
    }  | 
    ||
583  | 
    ✗✓ | 2  | 
    	if (!policy) { | 
    
584  | 
    TSerror(TS_R_UNACCEPTABLE_POLICY);  | 
    ||
585  | 
    TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,  | 
    ||
586  | 
    "Requested policy is not "  | 
    ||
587  | 
    "supported.");  | 
    ||
588  | 
    TS_RESP_CTX_add_failure_info(ctx, TS_INFO_UNACCEPTED_POLICY);  | 
    ||
589  | 
    }  | 
    ||
590  | 
    2  | 
    return policy;  | 
    |
591  | 
    2  | 
    }  | 
    |
592  | 
    |||
593  | 
    /* Creates the TS_TST_INFO object based on the settings of the context. */  | 
    ||
594  | 
    static TS_TST_INFO *  | 
    ||
595  | 
    TS_RESP_create_tst_info(TS_RESP_CTX *ctx, ASN1_OBJECT *policy)  | 
    ||
596  | 
    { | 
    ||
597  | 
    int result = 0;  | 
    ||
598  | 
    TS_TST_INFO *tst_info = NULL;  | 
    ||
599  | 
    ASN1_INTEGER *serial = NULL;  | 
    ||
600  | 
    ASN1_GENERALIZEDTIME *asn1_time = NULL;  | 
    ||
601  | 
    4  | 
    time_t sec;  | 
    |
602  | 
    2  | 
    long usec;  | 
    |
603  | 
    TS_ACCURACY *accuracy = NULL;  | 
    ||
604  | 
    const ASN1_INTEGER *nonce;  | 
    ||
605  | 
    GENERAL_NAME *tsa_name = NULL;  | 
    ||
606  | 
    |||
607  | 
    ✓✗ | 2  | 
    if (!(tst_info = TS_TST_INFO_new()))  | 
    
608  | 
    goto end;  | 
    ||
609  | 
    ✓✗ | 2  | 
    if (!TS_TST_INFO_set_version(tst_info, 1))  | 
    
610  | 
    goto end;  | 
    ||
611  | 
    ✓✗ | 2  | 
    if (!TS_TST_INFO_set_policy_id(tst_info, policy))  | 
    
612  | 
    goto end;  | 
    ||
613  | 
    ✓✗ | 2  | 
    if (!TS_TST_INFO_set_msg_imprint(tst_info, ctx->request->msg_imprint))  | 
    
614  | 
    goto end;  | 
    ||
615  | 
    ✓✗✓✗ | 
    4  | 
    if (!(serial = (*ctx->serial_cb)(ctx, ctx->serial_cb_data)) ||  | 
    
616  | 
    2  | 
    !TS_TST_INFO_set_serial(tst_info, serial))  | 
    |
617  | 
    goto end;  | 
    ||
618  | 
    ✓✗✓✗ | 
    4  | 
    if (!(*ctx->time_cb)(ctx, ctx->time_cb_data, &sec, &usec) ||  | 
    
619  | 
    4  | 
    !(asn1_time = TS_RESP_set_genTime_with_precision(NULL, sec, usec,  | 
    |
620  | 
    ✓✗ | 4  | 
    ctx->clock_precision_digits)) ||  | 
    
621  | 
    2  | 
    !TS_TST_INFO_set_time(tst_info, asn1_time))  | 
    |
622  | 
    goto end;  | 
    ||
623  | 
    |||
624  | 
    /* Setting accuracy if needed. */  | 
    ||
625  | 
    ✓✗✓✗ ✗✓✗✗  | 
    6  | 
    if ((ctx->seconds || ctx->millis || ctx->micros) &&  | 
    
626  | 
    !(accuracy = TS_ACCURACY_new()))  | 
    ||
627  | 
    goto end;  | 
    ||
628  | 
    |||
629  | 
    ✗✓✗✗ | 
    2  | 
    if (ctx->seconds && !TS_ACCURACY_set_seconds(accuracy, ctx->seconds))  | 
    
630  | 
    goto end;  | 
    ||
631  | 
    ✗✓✗✗ | 
    2  | 
    if (ctx->millis && !TS_ACCURACY_set_millis(accuracy, ctx->millis))  | 
    
632  | 
    goto end;  | 
    ||
633  | 
    ✗✓✗✗ | 
    2  | 
    if (ctx->micros && !TS_ACCURACY_set_micros(accuracy, ctx->micros))  | 
    
634  | 
    goto end;  | 
    ||
635  | 
    ✗✓✗✗ | 
    2  | 
    if (accuracy && !TS_TST_INFO_set_accuracy(tst_info, accuracy))  | 
    
636  | 
    goto end;  | 
    ||
637  | 
    |||
638  | 
    /* Setting ordering. */  | 
    ||
639  | 
    ✗✓✗✗ | 
    2  | 
    if ((ctx->flags & TS_ORDERING) &&  | 
    
640  | 
    !TS_TST_INFO_set_ordering(tst_info, 1))  | 
    ||
641  | 
    goto end;  | 
    ||
642  | 
    |||
643  | 
    /* Setting nonce if needed. */  | 
    ||
644  | 
    ✗✓✗✗ | 
    2  | 
    if ((nonce = TS_REQ_get_nonce(ctx->request)) != NULL &&  | 
    
645  | 
    !TS_TST_INFO_set_nonce(tst_info, nonce))  | 
    ||
646  | 
    goto end;  | 
    ||
647  | 
    |||
648  | 
    /* Setting TSA name to subject of signer certificate. */  | 
    ||
649  | 
    ✗✓ | 2  | 
    	if (ctx->flags & TS_TSA_NAME) { | 
    
650  | 
    if (!(tsa_name = GENERAL_NAME_new()))  | 
    ||
651  | 
    goto end;  | 
    ||
652  | 
    tsa_name->type = GEN_DIRNAME;  | 
    ||
653  | 
    tsa_name->d.dirn =  | 
    ||
654  | 
    X509_NAME_dup(ctx->signer_cert->cert_info->subject);  | 
    ||
655  | 
    if (!tsa_name->d.dirn)  | 
    ||
656  | 
    goto end;  | 
    ||
657  | 
    if (!TS_TST_INFO_set_tsa(tst_info, tsa_name))  | 
    ||
658  | 
    goto end;  | 
    ||
659  | 
    }  | 
    ||
660  | 
    |||
661  | 
    2  | 
    result = 1;  | 
    |
662  | 
    |||
663  | 
    end:  | 
    ||
664  | 
    ✗✓ | 2  | 
    	if (!result) { | 
    
665  | 
    TS_TST_INFO_free(tst_info);  | 
    ||
666  | 
    tst_info = NULL;  | 
    ||
667  | 
    TSerror(TS_R_TST_INFO_SETUP_ERROR);  | 
    ||
668  | 
    TS_RESP_CTX_set_status_info_cond(ctx, TS_STATUS_REJECTION,  | 
    ||
669  | 
    "Error during TSTInfo "  | 
    ||
670  | 
    "generation.");  | 
    ||
671  | 
    }  | 
    ||
672  | 
    2  | 
    GENERAL_NAME_free(tsa_name);  | 
    |
673  | 
    2  | 
    TS_ACCURACY_free(accuracy);  | 
    |
674  | 
    2  | 
    ASN1_GENERALIZEDTIME_free(asn1_time);  | 
    |
675  | 
    2  | 
    ASN1_INTEGER_free(serial);  | 
    |
676  | 
    |||
677  | 
    2  | 
    return tst_info;  | 
    |
678  | 
    2  | 
    }  | 
    |
679  | 
    |||
680  | 
    /* Processing the extensions of the request. */  | 
    ||
681  | 
    static int  | 
    ||
682  | 
    TS_RESP_process_extensions(TS_RESP_CTX *ctx)  | 
    ||
683  | 
    { | 
    ||
684  | 
    4  | 
    STACK_OF(X509_EXTENSION) *exts = TS_REQ_get_exts(ctx->request);  | 
    |
685  | 
    int i;  | 
    ||
686  | 
    int ok = 1;  | 
    ||
687  | 
    |||
688  | 
    ✓✗✗✓ | 
    6  | 
    	for (i = 0; ok && i < sk_X509_EXTENSION_num(exts); ++i) { | 
    
689  | 
    X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i);  | 
    ||
690  | 
    /* XXXXX The last argument was previously  | 
    ||
691  | 
    (void *)ctx->extension_cb, but ISO C doesn't permit  | 
    ||
692  | 
    converting a function pointer to void *. For lack of  | 
    ||
693  | 
    better information, I'm placing a NULL there instead.  | 
    ||
694  | 
    The callback can pick its own address out from the ctx  | 
    ||
695  | 
    anyway...  | 
    ||
696  | 
    */  | 
    ||
697  | 
    ok = (*ctx->extension_cb)(ctx, ext, NULL);  | 
    ||
698  | 
    }  | 
    ||
699  | 
    |||
700  | 
    2  | 
    return ok;  | 
    |
701  | 
    }  | 
    ||
702  | 
    |||
703  | 
    /* Functions for signing the TS_TST_INFO structure of the context. */  | 
    ||
704  | 
    static int  | 
    ||
705  | 
    TS_RESP_sign(TS_RESP_CTX *ctx)  | 
    ||
706  | 
    { | 
    ||
707  | 
    int ret = 0;  | 
    ||
708  | 
    PKCS7 *p7 = NULL;  | 
    ||
709  | 
    PKCS7_SIGNER_INFO *si;  | 
    ||
710  | 
    STACK_OF(X509) *certs; /* Certificates to include in sc. */  | 
    ||
711  | 
    ESS_SIGNING_CERT *sc = NULL;  | 
    ||
712  | 
    ASN1_OBJECT *oid;  | 
    ||
713  | 
    BIO *p7bio = NULL;  | 
    ||
714  | 
    int i;  | 
    ||
715  | 
    |||
716  | 
    /* Check if signcert and pkey match. */  | 
    ||
717  | 
    ✗✓ | 4  | 
    	if (!X509_check_private_key(ctx->signer_cert, ctx->signer_key)) { | 
    
718  | 
    TSerror(TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);  | 
    ||
719  | 
    goto err;  | 
    ||
720  | 
    }  | 
    ||
721  | 
    |||
722  | 
    /* Create a new PKCS7 signed object. */  | 
    ||
723  | 
    ✗✓ | 2  | 
    	if (!(p7 = PKCS7_new())) { | 
    
724  | 
    TSerror(ERR_R_MALLOC_FAILURE);  | 
    ||
725  | 
    goto err;  | 
    ||
726  | 
    }  | 
    ||
727  | 
    ✓✗ | 2  | 
    if (!PKCS7_set_type(p7, NID_pkcs7_signed))  | 
    
728  | 
    goto err;  | 
    ||
729  | 
    |||
730  | 
    /* Force SignedData version to be 3 instead of the default 1. */  | 
    ||
731  | 
    ✓✗ | 2  | 
    if (!ASN1_INTEGER_set(p7->d.sign->version, 3))  | 
    
732  | 
    goto err;  | 
    ||
733  | 
    |||
734  | 
    /* Add signer certificate and optional certificate chain. */  | 
    ||
735  | 
    ✗✓ | 2  | 
    	if (TS_REQ_get_cert_req(ctx->request)) { | 
    
736  | 
    PKCS7_add_certificate(p7, ctx->signer_cert);  | 
    ||
737  | 
    		if (ctx->certs) { | 
    ||
738  | 
    			for (i = 0; i < sk_X509_num(ctx->certs); ++i) { | 
    ||
739  | 
    X509 *cert = sk_X509_value(ctx->certs, i);  | 
    ||
740  | 
    PKCS7_add_certificate(p7, cert);  | 
    ||
741  | 
    }  | 
    ||
742  | 
    }  | 
    ||
743  | 
    }  | 
    ||
744  | 
    |||
745  | 
    /* Add a new signer info. */  | 
    ||
746  | 
    ✗✓ | 4  | 
    if (!(si = PKCS7_add_signature(p7, ctx->signer_cert,  | 
    
747  | 
    2  | 
    	    ctx->signer_key, EVP_sha1()))) { | 
    |
748  | 
    TSerror(TS_R_PKCS7_ADD_SIGNATURE_ERROR);  | 
    ||
749  | 
    goto err;  | 
    ||
750  | 
    }  | 
    ||
751  | 
    |||
752  | 
    /* Add content type signed attribute to the signer info. */  | 
    ||
753  | 
    2  | 
    oid = OBJ_nid2obj(NID_id_smime_ct_TSTInfo);  | 
    |
754  | 
    ✗✓ | 2  | 
    if (!PKCS7_add_signed_attribute(si, NID_pkcs9_contentType,  | 
    
755  | 
    2  | 
    	    V_ASN1_OBJECT, oid)) { | 
    |
756  | 
    TSerror(TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR);  | 
    ||
757  | 
    goto err;  | 
    ||
758  | 
    }  | 
    ||
759  | 
    |||
760  | 
    /* Create the ESS SigningCertificate attribute which contains  | 
    ||
761  | 
    the signer certificate id and optionally the certificate chain. */  | 
    ||
762  | 
    ✗✓ | 4  | 
    certs = ctx->flags & TS_ESS_CERT_ID_CHAIN ? ctx->certs : NULL;  | 
    
763  | 
    ✓✗ | 2  | 
    if (!(sc = ESS_SIGNING_CERT_new_init(ctx->signer_cert, certs)))  | 
    
764  | 
    goto err;  | 
    ||
765  | 
    |||
766  | 
    /* Add SigningCertificate signed attribute to the signer info. */  | 
    ||
767  | 
    ✗✓ | 2  | 
    	if (!ESS_add_signing_cert(si, sc)) { | 
    
768  | 
    TSerror(TS_R_ESS_ADD_SIGNING_CERT_ERROR);  | 
    ||
769  | 
    goto err;  | 
    ||
770  | 
    }  | 
    ||
771  | 
    |||
772  | 
    /* Add a new empty NID_id_smime_ct_TSTInfo encapsulated content. */  | 
    ||
773  | 
    ✓✗ | 2  | 
    if (!TS_TST_INFO_content_new(p7))  | 
    
774  | 
    goto err;  | 
    ||
775  | 
    |||
776  | 
    /* Add the DER encoded tst_info to the PKCS7 structure. */  | 
    ||
777  | 
    ✗✓ | 2  | 
    	if (!(p7bio = PKCS7_dataInit(p7, NULL))) { | 
    
778  | 
    TSerror(ERR_R_MALLOC_FAILURE);  | 
    ||
779  | 
    goto err;  | 
    ||
780  | 
    }  | 
    ||
781  | 
    |||
782  | 
    /* Convert tst_info to DER. */  | 
    ||
783  | 
    ✗✓ | 2  | 
    	if (!i2d_TS_TST_INFO_bio(p7bio, ctx->tst_info)) { | 
    
784  | 
    TSerror(TS_R_TS_DATASIGN);  | 
    ||
785  | 
    goto err;  | 
    ||
786  | 
    }  | 
    ||
787  | 
    |||
788  | 
    /* Create the signature and add it to the signer info. */  | 
    ||
789  | 
    ✗✓ | 2  | 
    	if (!PKCS7_dataFinal(p7, p7bio)) { | 
    
790  | 
    TSerror(TS_R_TS_DATASIGN);  | 
    ||
791  | 
    goto err;  | 
    ||
792  | 
    }  | 
    ||
793  | 
    |||
794  | 
    /* Set new PKCS7 and TST_INFO objects. */  | 
    ||
795  | 
    2  | 
    TS_RESP_set_tst_info(ctx->response, p7, ctx->tst_info);  | 
    |
796  | 
    p7 = NULL; /* Ownership is lost. */  | 
    ||
797  | 
    2  | 
    ctx->tst_info = NULL; /* Ownership is lost. */  | 
    |
798  | 
    |||
799  | 
    2  | 
    ret = 1;  | 
    |
800  | 
    |||
801  | 
    err:  | 
    ||
802  | 
    ✗✓ | 2  | 
    if (!ret)  | 
    
803  | 
    TS_RESP_CTX_set_status_info_cond(ctx, TS_STATUS_REJECTION,  | 
    ||
804  | 
    "Error during signature "  | 
    ||
805  | 
    "generation.");  | 
    ||
806  | 
    2  | 
    BIO_free_all(p7bio);  | 
    |
807  | 
    2  | 
    ESS_SIGNING_CERT_free(sc);  | 
    |
808  | 
    2  | 
    PKCS7_free(p7);  | 
    |
809  | 
    2  | 
    return ret;  | 
    |
810  | 
    }  | 
    ||
811  | 
    |||
812  | 
    static ESS_SIGNING_CERT *  | 
    ||
813  | 
    ESS_SIGNING_CERT_new_init(X509 *signcert, STACK_OF(X509) *certs)  | 
    ||
814  | 
    { | 
    ||
815  | 
    ESS_CERT_ID *cid;  | 
    ||
816  | 
    ESS_SIGNING_CERT *sc = NULL;  | 
    ||
817  | 
    int i;  | 
    ||
818  | 
    |||
819  | 
    /* Creating the ESS_CERT_ID stack. */  | 
    ||
820  | 
    ✓✗ | 4  | 
    if (!(sc = ESS_SIGNING_CERT_new()))  | 
    
821  | 
    goto err;  | 
    ||
822  | 
    ✗✓✗✗ | 
    2  | 
    if (!sc->cert_ids && !(sc->cert_ids = sk_ESS_CERT_ID_new_null()))  | 
    
823  | 
    goto err;  | 
    ||
824  | 
    |||
825  | 
    /* Adding the signing certificate id. */  | 
    ||
826  | 
    ✓✗✓✗ | 
    4  | 
    if (!(cid = ESS_CERT_ID_new_init(signcert, 0)) ||  | 
    
827  | 
    2  | 
    !sk_ESS_CERT_ID_push(sc->cert_ids, cid))  | 
    |
828  | 
    goto err;  | 
    ||
829  | 
    /* Adding the certificate chain ids. */  | 
    ||
830  | 
    ✗✓ | 4  | 
    	for (i = 0; i < sk_X509_num(certs); ++i) { | 
    
831  | 
    X509 *cert = sk_X509_value(certs, i);  | 
    ||
832  | 
    if (!(cid = ESS_CERT_ID_new_init(cert, 1)) ||  | 
    ||
833  | 
    !sk_ESS_CERT_ID_push(sc->cert_ids, cid))  | 
    ||
834  | 
    goto err;  | 
    ||
835  | 
    }  | 
    ||
836  | 
    |||
837  | 
    2  | 
    return sc;  | 
    |
838  | 
    |||
839  | 
    err:  | 
    ||
840  | 
    ESS_SIGNING_CERT_free(sc);  | 
    ||
841  | 
    TSerror(ERR_R_MALLOC_FAILURE);  | 
    ||
842  | 
    return NULL;  | 
    ||
843  | 
    2  | 
    }  | 
    |
844  | 
    |||
845  | 
    static ESS_CERT_ID *  | 
    ||
846  | 
    ESS_CERT_ID_new_init(X509 *cert, int issuer_needed)  | 
    ||
847  | 
    { | 
    ||
848  | 
    ESS_CERT_ID *cid = NULL;  | 
    ||
849  | 
    GENERAL_NAME *name = NULL;  | 
    ||
850  | 
    |||
851  | 
    /* Recompute SHA1 hash of certificate if necessary (side effect). */  | 
    ||
852  | 
    4  | 
    X509_check_purpose(cert, -1, 0);  | 
    |
853  | 
    |||
854  | 
    ✓✗ | 2  | 
    if (!(cid = ESS_CERT_ID_new()))  | 
    
855  | 
    goto err;  | 
    ||
856  | 
    ✓✗ | 2  | 
    if (!ASN1_OCTET_STRING_set(cid->hash, cert->sha1_hash,  | 
    
857  | 
    sizeof(cert->sha1_hash)))  | 
    ||
858  | 
    goto err;  | 
    ||
859  | 
    |||
860  | 
    /* Setting the issuer/serial if requested. */  | 
    ||
861  | 
    ✗✓ | 2  | 
    	if (issuer_needed) { | 
    
862  | 
    /* Creating issuer/serial structure. */  | 
    ||
863  | 
    if (!cid->issuer_serial &&  | 
    ||
864  | 
    !(cid->issuer_serial = ESS_ISSUER_SERIAL_new()))  | 
    ||
865  | 
    goto err;  | 
    ||
866  | 
    /* Creating general name from the certificate issuer. */  | 
    ||
867  | 
    if (!(name = GENERAL_NAME_new()))  | 
    ||
868  | 
    goto err;  | 
    ||
869  | 
    name->type = GEN_DIRNAME;  | 
    ||
870  | 
    if (!(name->d.dirn = X509_NAME_dup(cert->cert_info->issuer)))  | 
    ||
871  | 
    goto err;  | 
    ||
872  | 
    if (!sk_GENERAL_NAME_push(cid->issuer_serial->issuer, name))  | 
    ||
873  | 
    goto err;  | 
    ||
874  | 
    name = NULL; /* Ownership is lost. */  | 
    ||
875  | 
    /* Setting the serial number. */  | 
    ||
876  | 
    ASN1_INTEGER_free(cid->issuer_serial->serial);  | 
    ||
877  | 
    if (!(cid->issuer_serial->serial =  | 
    ||
878  | 
    ASN1_INTEGER_dup(cert->cert_info->serialNumber)))  | 
    ||
879  | 
    goto err;  | 
    ||
880  | 
    }  | 
    ||
881  | 
    |||
882  | 
    2  | 
    return cid;  | 
    |
883  | 
    |||
884  | 
    err:  | 
    ||
885  | 
    GENERAL_NAME_free(name);  | 
    ||
886  | 
    ESS_CERT_ID_free(cid);  | 
    ||
887  | 
    TSerror(ERR_R_MALLOC_FAILURE);  | 
    ||
888  | 
    return NULL;  | 
    ||
889  | 
    2  | 
    }  | 
    |
890  | 
    |||
891  | 
    static int  | 
    ||
892  | 
    TS_TST_INFO_content_new(PKCS7 *p7)  | 
    ||
893  | 
    { | 
    ||
894  | 
    PKCS7 *ret = NULL;  | 
    ||
895  | 
    ASN1_OCTET_STRING *octet_string = NULL;  | 
    ||
896  | 
    |||
897  | 
    /* Create new encapsulated NID_id_smime_ct_TSTInfo content. */  | 
    ||
898  | 
    ✓✗ | 4  | 
    if (!(ret = PKCS7_new()))  | 
    
899  | 
    goto err;  | 
    ||
900  | 
    ✓✗ | 2  | 
    if (!(ret->d.other = ASN1_TYPE_new()))  | 
    
901  | 
    goto err;  | 
    ||
902  | 
    2  | 
    ret->type = OBJ_nid2obj(NID_id_smime_ct_TSTInfo);  | 
    |
903  | 
    ✓✗ | 2  | 
    if (!(octet_string = ASN1_OCTET_STRING_new()))  | 
    
904  | 
    goto err;  | 
    ||
905  | 
    2  | 
    ASN1_TYPE_set(ret->d.other, V_ASN1_OCTET_STRING, octet_string);  | 
    |
906  | 
    octet_string = NULL;  | 
    ||
907  | 
    |||
908  | 
    /* Add encapsulated content to signed PKCS7 structure. */  | 
    ||
909  | 
    ✓✗ | 2  | 
    if (!PKCS7_set_content(p7, ret))  | 
    
910  | 
    goto err;  | 
    ||
911  | 
    |||
912  | 
    2  | 
    return 1;  | 
    |
913  | 
    |||
914  | 
    err:  | 
    ||
915  | 
    ASN1_OCTET_STRING_free(octet_string);  | 
    ||
916  | 
    PKCS7_free(ret);  | 
    ||
917  | 
    return 0;  | 
    ||
918  | 
    2  | 
    }  | 
    |
919  | 
    |||
920  | 
    static int  | 
    ||
921  | 
    ESS_add_signing_cert(PKCS7_SIGNER_INFO *si, ESS_SIGNING_CERT *sc)  | 
    ||
922  | 
    { | 
    ||
923  | 
    ASN1_STRING *seq = NULL;  | 
    ||
924  | 
    4  | 
    unsigned char *p, *pp = NULL;  | 
    |
925  | 
    int len;  | 
    ||
926  | 
    |||
927  | 
    2  | 
    len = i2d_ESS_SIGNING_CERT(sc, NULL);  | 
    |
928  | 
    ✗✓ | 2  | 
    	if (!(pp = malloc(len))) { | 
    
929  | 
    TSerror(ERR_R_MALLOC_FAILURE);  | 
    ||
930  | 
    goto err;  | 
    ||
931  | 
    }  | 
    ||
932  | 
    2  | 
    p = pp;  | 
    |
933  | 
    2  | 
    i2d_ESS_SIGNING_CERT(sc, &p);  | 
    |
934  | 
    ✓✗✗✓ | 
    4  | 
    	if (!(seq = ASN1_STRING_new()) || !ASN1_STRING_set(seq, pp, len)) { | 
    
935  | 
    TSerror(ERR_R_MALLOC_FAILURE);  | 
    ||
936  | 
    goto err;  | 
    ||
937  | 
    }  | 
    ||
938  | 
    2  | 
    free(pp);  | 
    |
939  | 
    pp = NULL;  | 
    ||
940  | 
    2  | 
    return PKCS7_add_signed_attribute(si,  | 
    |
941  | 
    2  | 
    NID_id_smime_aa_signingCertificate, V_ASN1_SEQUENCE, seq);  | 
    |
942  | 
    |||
943  | 
    err:  | 
    ||
944  | 
    ASN1_STRING_free(seq);  | 
    ||
945  | 
    free(pp);  | 
    ||
946  | 
    |||
947  | 
    return 0;  | 
    ||
948  | 
    2  | 
    }  | 
    |
949  | 
    |||
950  | 
    |||
951  | 
    static ASN1_GENERALIZEDTIME *  | 
    ||
952  | 
    TS_RESP_set_genTime_with_precision(ASN1_GENERALIZEDTIME *asn1_time,  | 
    ||
953  | 
    time_t sec, long usec, unsigned precision)  | 
    ||
954  | 
    { | 
    ||
955  | 
    struct tm *tm = NULL;  | 
    ||
956  | 
    2  | 
    char genTime_str[17 + TS_MAX_CLOCK_PRECISION_DIGITS];  | 
    |
957  | 
    2  | 
    char usecstr[TS_MAX_CLOCK_PRECISION_DIGITS + 2];  | 
    |
958  | 
    char *p;  | 
    ||
959  | 
    int rv;  | 
    ||
960  | 
    |||
961  | 
    ✓✗ | 2  | 
    if (precision > TS_MAX_CLOCK_PRECISION_DIGITS)  | 
    
962  | 
    goto err;  | 
    ||
963  | 
    |||
964  | 
    ✓✗ | 2  | 
    if (!(tm = gmtime(&sec)))  | 
    
965  | 
    goto err;  | 
    ||
966  | 
    |||
967  | 
    /*  | 
    ||
968  | 
    * Put "genTime_str" in GeneralizedTime format. We work around the  | 
    ||
969  | 
    * restrictions imposed by rfc3280 (i.e. "GeneralizedTime values MUST  | 
    ||
970  | 
    * NOT include fractional seconds") and OpenSSL related functions to  | 
    ||
971  | 
    * meet the rfc3161 requirement: "GeneralizedTime syntax can include  | 
    ||
972  | 
    * fraction-of-second details".  | 
    ||
973  | 
    */  | 
    ||
974  | 
    ✗✓ | 2  | 
    	if (precision > 0) { | 
    
975  | 
    /* To make things a bit harder, X.690 | ISO/IEC 8825-1 provides  | 
    ||
976  | 
    the following restrictions for a DER-encoding, which OpenSSL  | 
    ||
977  | 
    (specifically ASN1_GENERALIZEDTIME_check() function) doesn't  | 
    ||
978  | 
    support:  | 
    ||
979  | 
    "The encoding MUST terminate with a "Z" (which means "Zulu"  | 
    ||
980  | 
    time). The decimal point element, if present, MUST be the  | 
    ||
981  | 
    point option ".". The fractional-seconds elements,  | 
    ||
982  | 
    if present, MUST omit all trailing 0's;  | 
    ||
983  | 
    if the elements correspond to 0, they MUST be wholly  | 
    ||
984  | 
    omitted, and the decimal point element also MUST be  | 
    ||
985  | 
    omitted." */  | 
    ||
986  | 
    (void) snprintf(usecstr, sizeof(usecstr), ".%06ld", usec);  | 
    ||
987  | 
    /* truncate and trim trailing 0 */  | 
    ||
988  | 
    usecstr[precision + 1] = '\0';  | 
    ||
989  | 
    p = usecstr + strlen(usecstr) - 1;  | 
    ||
990  | 
    while (p > usecstr && *p == '0')  | 
    ||
991  | 
    *p-- = '\0';  | 
    ||
992  | 
    /* if we've reached the beginning, delete the . too */  | 
    ||
993  | 
    if (p == usecstr)  | 
    ||
994  | 
    *p = '\0';  | 
    ||
995  | 
    |||
996  | 
    	} else { | 
    ||
997  | 
    /* empty */  | 
    ||
998  | 
    2  | 
    usecstr[0] = '\0';  | 
    |
999  | 
    }  | 
    ||
1000  | 
    6  | 
    rv = snprintf(genTime_str, sizeof(genTime_str),  | 
    |
1001  | 
    "%04d%02d%02d%02d%02d%02d%sZ",  | 
    ||
1002  | 
    2  | 
    tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,  | 
    |
1003  | 
    2  | 
    tm->tm_hour, tm->tm_min, tm->tm_sec, usecstr);  | 
    |
1004  | 
    ✓✗✓✗ | 
    4  | 
    if (rv == -1 || rv >= sizeof(genTime_str))  | 
    
1005  | 
    goto err;  | 
    ||
1006  | 
    |||
1007  | 
    /* Now call OpenSSL to check and set our genTime value */  | 
    ||
1008  | 
    ✓✗✓✗ | 
    4  | 
    if (!asn1_time && !(asn1_time = ASN1_GENERALIZEDTIME_new()))  | 
    
1009  | 
    goto err;  | 
    ||
1010  | 
    ✗✓ | 2  | 
    	if (!ASN1_GENERALIZEDTIME_set_string(asn1_time, genTime_str)) { | 
    
1011  | 
    ASN1_GENERALIZEDTIME_free(asn1_time);  | 
    ||
1012  | 
    goto err;  | 
    ||
1013  | 
    }  | 
    ||
1014  | 
    |||
1015  | 
    2  | 
    return asn1_time;  | 
    |
1016  | 
    |||
1017  | 
    err:  | 
    ||
1018  | 
    TSerror(TS_R_COULD_NOT_SET_TIME);  | 
    ||
1019  | 
    return NULL;  | 
    ||
1020  | 
    2  | 
    }  | 
    
| Generated by: GCOVR (Version 3.3) |