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