ts.c (256281) | ts.c (280304) |
---|---|
1/* apps/ts.c */ | 1/* apps/ts.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) 2001 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) 2001 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: --- 41 unchanged lines hidden (view full) --- 63#include <openssl/bio.h> 64#include <openssl/err.h> 65#include <openssl/pem.h> 66#include <openssl/rand.h> 67#include <openssl/ts.h> 68#include <openssl/bn.h> 69 70#undef PROG | 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: --- 41 unchanged lines hidden (view full) --- 64#include <openssl/bio.h> 65#include <openssl/err.h> 66#include <openssl/pem.h> 67#include <openssl/rand.h> 68#include <openssl/ts.h> 69#include <openssl/bn.h> 70 71#undef PROG |
71#define PROG ts_main | 72#define PROG ts_main |
72 73/* Length of the nonce of the request in bits (must be a multiple of 8). */ | 73 74/* Length of the nonce of the request in bits (must be a multiple of 8). */ |
74#define NONCE_LENGTH 64 | 75#define NONCE_LENGTH 64 |
75 76/* Macro definitions for the configuration file. */ | 76 77/* Macro definitions for the configuration file. */ |
77#define ENV_OID_FILE "oid_file" | 78#define ENV_OID_FILE "oid_file" |
78 79/* Local function declarations. */ 80 81static ASN1_OBJECT *txt2obj(const char *oid); 82static CONF *load_config_file(const char *configfile); 83 84/* Query related functions. */ 85static int query_command(const char *data, char *digest, | 79 80/* Local function declarations. */ 81 82static ASN1_OBJECT *txt2obj(const char *oid); 83static CONF *load_config_file(const char *configfile); 84 85/* Query related functions. */ 86static int query_command(const char *data, char *digest, |
86 const EVP_MD *md, const char *policy, int no_nonce, 87 int cert, const char *in, const char *out, int text); 88static BIO *BIO_open_with_default(const char *file, const char *mode, 89 FILE *default_fp); | 87 const EVP_MD *md, const char *policy, int no_nonce, 88 int cert, const char *in, const char *out, int text); 89static BIO *BIO_open_with_default(const char *file, const char *mode, 90 FILE *default_fp); |
90static TS_REQ *create_query(BIO *data_bio, char *digest, const EVP_MD *md, | 91static TS_REQ *create_query(BIO *data_bio, char *digest, const EVP_MD *md, |
91 const char *policy, int no_nonce, int cert); | 92 const char *policy, int no_nonce, int cert); |
92static int create_digest(BIO *input, char *digest, | 93static int create_digest(BIO *input, char *digest, |
93 const EVP_MD *md, unsigned char **md_value); | 94 const EVP_MD *md, unsigned char **md_value); |
94static ASN1_INTEGER *create_nonce(int bits); 95 96/* Reply related functions. */ | 95static ASN1_INTEGER *create_nonce(int bits); 96 97/* Reply related functions. */ |
97static int reply_command(CONF *conf, char *section, char *engine, 98 char *queryfile, char *passin, char *inkey, 99 char *signer, char *chain, const char *policy, 100 char *in, int token_in, char *out, int token_out, 101 int text); | 98static int reply_command(CONF *conf, char *section, char *engine, 99 char *queryfile, char *passin, char *inkey, 100 char *signer, char *chain, const char *policy, 101 char *in, int token_in, char *out, int token_out, 102 int text); |
102static TS_RESP *read_PKCS7(BIO *in_bio); 103static TS_RESP *create_response(CONF *conf, const char *section, char *engine, | 103static TS_RESP *read_PKCS7(BIO *in_bio); 104static TS_RESP *create_response(CONF *conf, const char *section, char *engine, |
104 char *queryfile, char *passin, char *inkey, 105 char *signer, char *chain, const char *policy); 106static ASN1_INTEGER * MS_CALLBACK serial_cb(TS_RESP_CTX *ctx, void *data); | 105 char *queryfile, char *passin, char *inkey, 106 char *signer, char *chain, 107 const char *policy); 108static ASN1_INTEGER *MS_CALLBACK serial_cb(TS_RESP_CTX *ctx, void *data); |
107static ASN1_INTEGER *next_serial(const char *serialfile); 108static int save_ts_serial(const char *serialfile, ASN1_INTEGER *serial); 109 110/* Verify related functions. */ 111static int verify_command(char *data, char *digest, char *queryfile, | 109static ASN1_INTEGER *next_serial(const char *serialfile); 110static int save_ts_serial(const char *serialfile, ASN1_INTEGER *serial); 111 112/* Verify related functions. */ 113static int verify_command(char *data, char *digest, char *queryfile, |
112 char *in, int token_in, 113 char *ca_path, char *ca_file, char *untrusted); 114static TS_VERIFY_CTX *create_verify_ctx(char *data, char *digest, 115 char *queryfile, 116 char *ca_path, char *ca_file, 117 char *untrusted); | 114 char *in, int token_in, 115 char *ca_path, char *ca_file, char *untrusted); 116static TS_VERIFY_CTX *create_verify_ctx(char *data, char *digest, 117 char *queryfile, 118 char *ca_path, char *ca_file, 119 char *untrusted); |
118static X509_STORE *create_cert_store(char *ca_path, char *ca_file); 119static int MS_CALLBACK verify_cb(int ok, X509_STORE_CTX *ctx); 120 121/* Main function definition. */ 122int MAIN(int, char **); 123 124int MAIN(int argc, char **argv) | 120static X509_STORE *create_cert_store(char *ca_path, char *ca_file); 121static int MS_CALLBACK verify_cb(int ok, X509_STORE_CTX *ctx); 122 123/* Main function definition. */ 124int MAIN(int, char **); 125 126int MAIN(int argc, char **argv) |
125 { 126 int ret = 1; 127 char *configfile = NULL; 128 char *section = NULL; 129 CONF *conf = NULL; 130 enum mode { 131 CMD_NONE, CMD_QUERY, CMD_REPLY, CMD_VERIFY 132 } mode = CMD_NONE; 133 char *data = NULL; 134 char *digest = NULL; 135 const EVP_MD *md = NULL; 136 char *rnd = NULL; 137 char *policy = NULL; 138 int no_nonce = 0; 139 int cert = 0; 140 char *in = NULL; 141 char *out = NULL; 142 int text = 0; 143 char *queryfile = NULL; 144 char *passin = NULL; /* Password source. */ 145 char *password =NULL; /* Password itself. */ 146 char *inkey = NULL; 147 char *signer = NULL; 148 char *chain = NULL; 149 char *ca_path = NULL; 150 char *ca_file = NULL; 151 char *untrusted = NULL; 152 char *engine = NULL; 153 /* Input is ContentInfo instead of TimeStampResp. */ 154 int token_in = 0; 155 /* Output is ContentInfo instead of TimeStampResp. */ 156 int token_out = 0; 157 int free_bio_err = 0; | 127{ 128 int ret = 1; 129 char *configfile = NULL; 130 char *section = NULL; 131 CONF *conf = NULL; 132 enum mode { 133 CMD_NONE, CMD_QUERY, CMD_REPLY, CMD_VERIFY 134 } mode = CMD_NONE; 135 char *data = NULL; 136 char *digest = NULL; 137 const EVP_MD *md = NULL; 138 char *rnd = NULL; 139 char *policy = NULL; 140 int no_nonce = 0; 141 int cert = 0; 142 char *in = NULL; 143 char *out = NULL; 144 int text = 0; 145 char *queryfile = NULL; 146 char *passin = NULL; /* Password source. */ 147 char *password = NULL; /* Password itself. */ 148 char *inkey = NULL; 149 char *signer = NULL; 150 char *chain = NULL; 151 char *ca_path = NULL; 152 char *ca_file = NULL; 153 char *untrusted = NULL; 154 char *engine = NULL; 155 /* Input is ContentInfo instead of TimeStampResp. */ 156 int token_in = 0; 157 /* Output is ContentInfo instead of TimeStampResp. */ 158 int token_out = 0; 159 int free_bio_err = 0; |
158 | 160 |
159 ERR_load_crypto_strings(); 160 apps_startup(); | 161 ERR_load_crypto_strings(); 162 apps_startup(); |
161 | 163 |
162 if (bio_err == NULL && (bio_err = BIO_new(BIO_s_file())) != NULL) 163 { 164 free_bio_err = 1; 165 BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); 166 } | 164 if (bio_err == NULL && (bio_err = BIO_new(BIO_s_file())) != NULL) { 165 free_bio_err = 1; 166 BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); 167 } |
167 | 168 |
168 if (!load_config(bio_err, NULL)) 169 goto cleanup; | 169 if (!load_config(bio_err, NULL)) 170 goto cleanup; |
170 | 171 |
171 for (argc--, argv++; argc > 0; argc--, argv++) 172 { 173 if (strcmp(*argv, "-config") == 0) 174 { 175 if (argc-- < 1) goto usage; 176 configfile = *++argv; 177 } 178 else if (strcmp(*argv, "-section") == 0) 179 { 180 if (argc-- < 1) goto usage; 181 section = *++argv; 182 } 183 else if (strcmp(*argv, "-query") == 0) 184 { 185 if (mode != CMD_NONE) goto usage; 186 mode = CMD_QUERY; 187 } 188 else if (strcmp(*argv, "-data") == 0) 189 { 190 if (argc-- < 1) goto usage; 191 data = *++argv; 192 } 193 else if (strcmp(*argv, "-digest") == 0) 194 { 195 if (argc-- < 1) goto usage; 196 digest = *++argv; 197 } 198 else if (strcmp(*argv, "-rand") == 0) 199 { 200 if (argc-- < 1) goto usage; 201 rnd = *++argv; 202 } 203 else if (strcmp(*argv, "-policy") == 0) 204 { 205 if (argc-- < 1) goto usage; 206 policy = *++argv; 207 } 208 else if (strcmp(*argv, "-no_nonce") == 0) 209 { 210 no_nonce = 1; 211 } 212 else if (strcmp(*argv, "-cert") == 0) 213 { 214 cert = 1; 215 } 216 else if (strcmp(*argv, "-in") == 0) 217 { 218 if (argc-- < 1) goto usage; 219 in = *++argv; 220 } 221 else if (strcmp(*argv, "-token_in") == 0) 222 { 223 token_in = 1; 224 } 225 else if (strcmp(*argv, "-out") == 0) 226 { 227 if (argc-- < 1) goto usage; 228 out = *++argv; 229 } 230 else if (strcmp(*argv, "-token_out") == 0) 231 { 232 token_out = 1; 233 } 234 else if (strcmp(*argv, "-text") == 0) 235 { 236 text = 1; 237 } 238 else if (strcmp(*argv, "-reply") == 0) 239 { 240 if (mode != CMD_NONE) goto usage; 241 mode = CMD_REPLY; 242 } 243 else if (strcmp(*argv, "-queryfile") == 0) 244 { 245 if (argc-- < 1) goto usage; 246 queryfile = *++argv; 247 } 248 else if (strcmp(*argv, "-passin") == 0) 249 { 250 if (argc-- < 1) goto usage; 251 passin = *++argv; 252 } 253 else if (strcmp(*argv, "-inkey") == 0) 254 { 255 if (argc-- < 1) goto usage; 256 inkey = *++argv; 257 } 258 else if (strcmp(*argv, "-signer") == 0) 259 { 260 if (argc-- < 1) goto usage; 261 signer = *++argv; 262 } 263 else if (strcmp(*argv, "-chain") == 0) 264 { 265 if (argc-- < 1) goto usage; 266 chain = *++argv; 267 } 268 else if (strcmp(*argv, "-verify") == 0) 269 { 270 if (mode != CMD_NONE) goto usage; 271 mode = CMD_VERIFY; 272 } 273 else if (strcmp(*argv, "-CApath") == 0) 274 { 275 if (argc-- < 1) goto usage; 276 ca_path = *++argv; 277 } 278 else if (strcmp(*argv, "-CAfile") == 0) 279 { 280 if (argc-- < 1) goto usage; 281 ca_file = *++argv; 282 } 283 else if (strcmp(*argv, "-untrusted") == 0) 284 { 285 if (argc-- < 1) goto usage; 286 untrusted = *++argv; 287 } 288 else if (strcmp(*argv, "-engine") == 0) 289 { 290 if (argc-- < 1) goto usage; 291 engine = *++argv; 292 } 293 else if ((md = EVP_get_digestbyname(*argv + 1)) != NULL) 294 { 295 /* empty. */ 296 } 297 else 298 goto usage; 299 } 300 301 /* Seed the random number generator if it is going to be used. */ 302 if (mode == CMD_QUERY && !no_nonce) 303 { 304 if (!app_RAND_load_file(NULL, bio_err, 1) && rnd == NULL) 305 BIO_printf(bio_err, "warning, not much extra random " 306 "data, consider using the -rand option\n"); 307 if (rnd != NULL) 308 BIO_printf(bio_err,"%ld semi-random bytes loaded\n", 309 app_RAND_load_files(rnd)); 310 } | 172 for (argc--, argv++; argc > 0; argc--, argv++) { 173 if (strcmp(*argv, "-config") == 0) { 174 if (argc-- < 1) 175 goto usage; 176 configfile = *++argv; 177 } else if (strcmp(*argv, "-section") == 0) { 178 if (argc-- < 1) 179 goto usage; 180 section = *++argv; 181 } else if (strcmp(*argv, "-query") == 0) { 182 if (mode != CMD_NONE) 183 goto usage; 184 mode = CMD_QUERY; 185 } else if (strcmp(*argv, "-data") == 0) { 186 if (argc-- < 1) 187 goto usage; 188 data = *++argv; 189 } else if (strcmp(*argv, "-digest") == 0) { 190 if (argc-- < 1) 191 goto usage; 192 digest = *++argv; 193 } else if (strcmp(*argv, "-rand") == 0) { 194 if (argc-- < 1) 195 goto usage; 196 rnd = *++argv; 197 } else if (strcmp(*argv, "-policy") == 0) { 198 if (argc-- < 1) 199 goto usage; 200 policy = *++argv; 201 } else if (strcmp(*argv, "-no_nonce") == 0) { 202 no_nonce = 1; 203 } else if (strcmp(*argv, "-cert") == 0) { 204 cert = 1; 205 } else if (strcmp(*argv, "-in") == 0) { 206 if (argc-- < 1) 207 goto usage; 208 in = *++argv; 209 } else if (strcmp(*argv, "-token_in") == 0) { 210 token_in = 1; 211 } else if (strcmp(*argv, "-out") == 0) { 212 if (argc-- < 1) 213 goto usage; 214 out = *++argv; 215 } else if (strcmp(*argv, "-token_out") == 0) { 216 token_out = 1; 217 } else if (strcmp(*argv, "-text") == 0) { 218 text = 1; 219 } else if (strcmp(*argv, "-reply") == 0) { 220 if (mode != CMD_NONE) 221 goto usage; 222 mode = CMD_REPLY; 223 } else if (strcmp(*argv, "-queryfile") == 0) { 224 if (argc-- < 1) 225 goto usage; 226 queryfile = *++argv; 227 } else if (strcmp(*argv, "-passin") == 0) { 228 if (argc-- < 1) 229 goto usage; 230 passin = *++argv; 231 } else if (strcmp(*argv, "-inkey") == 0) { 232 if (argc-- < 1) 233 goto usage; 234 inkey = *++argv; 235 } else if (strcmp(*argv, "-signer") == 0) { 236 if (argc-- < 1) 237 goto usage; 238 signer = *++argv; 239 } else if (strcmp(*argv, "-chain") == 0) { 240 if (argc-- < 1) 241 goto usage; 242 chain = *++argv; 243 } else if (strcmp(*argv, "-verify") == 0) { 244 if (mode != CMD_NONE) 245 goto usage; 246 mode = CMD_VERIFY; 247 } else if (strcmp(*argv, "-CApath") == 0) { 248 if (argc-- < 1) 249 goto usage; 250 ca_path = *++argv; 251 } else if (strcmp(*argv, "-CAfile") == 0) { 252 if (argc-- < 1) 253 goto usage; 254 ca_file = *++argv; 255 } else if (strcmp(*argv, "-untrusted") == 0) { 256 if (argc-- < 1) 257 goto usage; 258 untrusted = *++argv; 259 } else if (strcmp(*argv, "-engine") == 0) { 260 if (argc-- < 1) 261 goto usage; 262 engine = *++argv; 263 } else if ((md = EVP_get_digestbyname(*argv + 1)) != NULL) { 264 /* empty. */ 265 } else 266 goto usage; 267 } |
311 | 268 |
312 /* Get the password if required. */ 313 if(mode == CMD_REPLY && passin && 314 !app_passwd(bio_err, passin, NULL, &password, NULL)) 315 { 316 BIO_printf(bio_err,"Error getting password.\n"); 317 goto cleanup; 318 } | 269 /* Seed the random number generator if it is going to be used. */ 270 if (mode == CMD_QUERY && !no_nonce) { 271 if (!app_RAND_load_file(NULL, bio_err, 1) && rnd == NULL) 272 BIO_printf(bio_err, "warning, not much extra random " 273 "data, consider using the -rand option\n"); 274 if (rnd != NULL) 275 BIO_printf(bio_err, "%ld semi-random bytes loaded\n", 276 app_RAND_load_files(rnd)); 277 } |
319 | 278 |
320 /* Check consistency of parameters and execute 321 the appropriate function. */ 322 switch (mode) 323 { 324 case CMD_NONE: 325 goto usage; 326 case CMD_QUERY: 327 /* Data file and message imprint cannot be specified 328 at the same time. */ 329 ret = data != NULL && digest != NULL; 330 if (ret) goto usage; 331 /* Load the config file for possible policy OIDs. */ 332 conf = load_config_file(configfile); 333 ret = !query_command(data, digest, md, policy, no_nonce, cert, 334 in, out, text); 335 break; 336 case CMD_REPLY: 337 conf = load_config_file(configfile); 338 if (in == NULL) 339 { 340 ret = !(queryfile != NULL && conf != NULL && !token_in); 341 if (ret) goto usage; 342 } 343 else 344 { 345 /* 'in' and 'queryfile' are exclusive. */ 346 ret = !(queryfile == NULL); 347 if (ret) goto usage; 348 } | 279 /* Get the password if required. */ 280 if (mode == CMD_REPLY && passin && 281 !app_passwd(bio_err, passin, NULL, &password, NULL)) { 282 BIO_printf(bio_err, "Error getting password.\n"); 283 goto cleanup; 284 } |
349 | 285 |
350 ret = !reply_command(conf, section, engine, queryfile, 351 password, inkey, signer, chain, policy, 352 in, token_in, out, token_out, text); 353 break; 354 case CMD_VERIFY: 355 ret = !(((queryfile && !data && !digest) 356 || (!queryfile && data && !digest) 357 || (!queryfile && !data && digest)) 358 && in != NULL); 359 if (ret) goto usage; | 286 /* 287 * Check consistency of parameters and execute the appropriate function. 288 */ 289 switch (mode) { 290 case CMD_NONE: 291 goto usage; 292 case CMD_QUERY: 293 /* 294 * Data file and message imprint cannot be specified at the same 295 * time. 296 */ 297 ret = data != NULL && digest != NULL; 298 if (ret) 299 goto usage; 300 /* Load the config file for possible policy OIDs. */ 301 conf = load_config_file(configfile); 302 ret = !query_command(data, digest, md, policy, no_nonce, cert, 303 in, out, text); 304 break; 305 case CMD_REPLY: 306 conf = load_config_file(configfile); 307 if (in == NULL) { 308 ret = !(queryfile != NULL && conf != NULL && !token_in); 309 if (ret) 310 goto usage; 311 } else { 312 /* 'in' and 'queryfile' are exclusive. */ 313 ret = !(queryfile == NULL); 314 if (ret) 315 goto usage; 316 } |
360 | 317 |
361 ret = !verify_command(data, digest, queryfile, in, token_in, 362 ca_path, ca_file, untrusted); 363 } | 318 ret = !reply_command(conf, section, engine, queryfile, 319 password, inkey, signer, chain, policy, 320 in, token_in, out, token_out, text); 321 break; 322 case CMD_VERIFY: 323 ret = !(((queryfile && !data && !digest) 324 || (!queryfile && data && !digest) 325 || (!queryfile && !data && digest)) 326 && in != NULL); 327 if (ret) 328 goto usage; |
364 | 329 |
365 goto cleanup; | 330 ret = !verify_command(data, digest, queryfile, in, token_in, 331 ca_path, ca_file, untrusted); 332 } |
366 | 333 |
334 goto cleanup; 335 |
|
367 usage: | 336 usage: |
368 BIO_printf(bio_err, "usage:\n" 369 "ts -query [-rand file%cfile%c...] [-config configfile] " 370 "[-data file_to_hash] [-digest digest_bytes]" 371 "[-md2|-md4|-md5|-sha|-sha1|-mdc2|-ripemd160] " 372 "[-policy object_id] [-no_nonce] [-cert] " 373 "[-in request.tsq] [-out request.tsq] [-text]\n", 374 LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR); 375 BIO_printf(bio_err, "or\n" 376 "ts -reply [-config configfile] [-section tsa_section] " 377 "[-queryfile request.tsq] [-passin password] " 378 "[-signer tsa_cert.pem] [-inkey private_key.pem] " 379 "[-chain certs_file.pem] [-policy object_id] " 380 "[-in response.tsr] [-token_in] " 381 "[-out response.tsr] [-token_out] [-text] [-engine id]\n"); 382 BIO_printf(bio_err, "or\n" 383 "ts -verify [-data file_to_hash] [-digest digest_bytes] " 384 "[-queryfile request.tsq] " 385 "-in response.tsr [-token_in] " 386 "-CApath ca_path -CAfile ca_file.pem " 387 "-untrusted cert_file.pem\n"); | 337 BIO_printf(bio_err, "usage:\n" 338 "ts -query [-rand file%cfile%c...] [-config configfile] " 339 "[-data file_to_hash] [-digest digest_bytes]" 340 "[-md2|-md4|-md5|-sha|-sha1|-mdc2|-ripemd160] " 341 "[-policy object_id] [-no_nonce] [-cert] " 342 "[-in request.tsq] [-out request.tsq] [-text]\n", 343 LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR); 344 BIO_printf(bio_err, "or\n" 345 "ts -reply [-config configfile] [-section tsa_section] " 346 "[-queryfile request.tsq] [-passin password] " 347 "[-signer tsa_cert.pem] [-inkey private_key.pem] " 348 "[-chain certs_file.pem] [-policy object_id] " 349 "[-in response.tsr] [-token_in] " 350 "[-out response.tsr] [-token_out] [-text] [-engine id]\n"); 351 BIO_printf(bio_err, "or\n" 352 "ts -verify [-data file_to_hash] [-digest digest_bytes] " 353 "[-queryfile request.tsq] " 354 "-in response.tsr [-token_in] " 355 "-CApath ca_path -CAfile ca_file.pem " 356 "-untrusted cert_file.pem\n"); |
388 cleanup: | 357 cleanup: |
389 /* Clean up. */ 390 app_RAND_write_file(NULL, bio_err); 391 NCONF_free(conf); 392 OPENSSL_free(password); 393 OBJ_cleanup(); 394 if (free_bio_err) 395 { 396 BIO_free_all(bio_err); 397 bio_err = NULL; 398 } | 358 /* Clean up. */ 359 app_RAND_write_file(NULL, bio_err); 360 NCONF_free(conf); 361 OPENSSL_free(password); 362 OBJ_cleanup(); 363 if (free_bio_err) { 364 BIO_free_all(bio_err); 365 bio_err = NULL; 366 } |
399 | 367 |
400 OPENSSL_EXIT(ret); 401 } | 368 OPENSSL_EXIT(ret); 369} |
402 403/* 404 * Configuration file-related function definitions. 405 */ 406 407static ASN1_OBJECT *txt2obj(const char *oid) | 370 371/* 372 * Configuration file-related function definitions. 373 */ 374 375static ASN1_OBJECT *txt2obj(const char *oid) |
408 { 409 ASN1_OBJECT *oid_obj = NULL; | 376{ 377 ASN1_OBJECT *oid_obj = NULL; |
410 | 378 |
411 if (!(oid_obj = OBJ_txt2obj(oid, 0))) 412 BIO_printf(bio_err, "cannot convert %s to OID\n", oid); | 379 if (!(oid_obj = OBJ_txt2obj(oid, 0))) 380 BIO_printf(bio_err, "cannot convert %s to OID\n", oid); |
413 | 381 |
414 return oid_obj; 415 } | 382 return oid_obj; 383} |
416 417static CONF *load_config_file(const char *configfile) | 384 385static CONF *load_config_file(const char *configfile) |
418 { 419 CONF *conf = NULL; 420 long errorline = -1; | 386{ 387 CONF *conf = NULL; 388 long errorline = -1; |
421 | 389 |
422 if (!configfile) configfile = getenv("OPENSSL_CONF"); 423 if (!configfile) configfile = getenv("SSLEAY_CONF"); | 390 if (!configfile) 391 configfile = getenv("OPENSSL_CONF"); 392 if (!configfile) 393 configfile = getenv("SSLEAY_CONF"); |
424 | 394 |
425 if (configfile && 426 (!(conf = NCONF_new(NULL)) || 427 NCONF_load(conf, configfile, &errorline) <= 0)) 428 { 429 if (errorline <= 0) 430 BIO_printf(bio_err, "error loading the config file " 431 "'%s'\n", configfile); 432 else 433 BIO_printf(bio_err, "error on line %ld of config file " 434 "'%s'\n", errorline, configfile); 435 } | 395 if (configfile && 396 (!(conf = NCONF_new(NULL)) || 397 NCONF_load(conf, configfile, &errorline) <= 0)) { 398 if (errorline <= 0) 399 BIO_printf(bio_err, "error loading the config file " 400 "'%s'\n", configfile); 401 else 402 BIO_printf(bio_err, "error on line %ld of config file " 403 "'%s'\n", errorline, configfile); 404 } |
436 | 405 |
437 if (conf != NULL) 438 { 439 const char *p; | 406 if (conf != NULL) { 407 const char *p; |
440 | 408 |
441 BIO_printf(bio_err,"Using configuration from %s\n", configfile); 442 p = NCONF_get_string(conf, NULL, ENV_OID_FILE); 443 if (p != NULL) 444 { 445 BIO *oid_bio = BIO_new_file(p, "r"); 446 if (!oid_bio) 447 ERR_print_errors(bio_err); 448 else 449 { 450 OBJ_create_objects(oid_bio); 451 BIO_free_all(oid_bio); 452 } 453 } 454 else 455 ERR_clear_error(); 456 if(!add_oid_section(bio_err, conf)) 457 ERR_print_errors(bio_err); 458 } 459 return conf; 460 } | 409 BIO_printf(bio_err, "Using configuration from %s\n", configfile); 410 p = NCONF_get_string(conf, NULL, ENV_OID_FILE); 411 if (p != NULL) { 412 BIO *oid_bio = BIO_new_file(p, "r"); 413 if (!oid_bio) 414 ERR_print_errors(bio_err); 415 else { 416 OBJ_create_objects(oid_bio); 417 BIO_free_all(oid_bio); 418 } 419 } else 420 ERR_clear_error(); 421 if (!add_oid_section(bio_err, conf)) 422 ERR_print_errors(bio_err); 423 } 424 return conf; 425} |
461 462/* 463 * Query-related method definitions. 464 */ 465 466static int query_command(const char *data, char *digest, const EVP_MD *md, | 426 427/* 428 * Query-related method definitions. 429 */ 430 431static int query_command(const char *data, char *digest, const EVP_MD *md, |
467 const char *policy, int no_nonce, 468 int cert, const char *in, const char *out, int text) 469 { 470 int ret = 0; 471 TS_REQ *query = NULL; 472 BIO *in_bio = NULL; 473 BIO *data_bio = NULL; 474 BIO *out_bio = NULL; | 432 const char *policy, int no_nonce, 433 int cert, const char *in, const char *out, int text) 434{ 435 int ret = 0; 436 TS_REQ *query = NULL; 437 BIO *in_bio = NULL; 438 BIO *data_bio = NULL; 439 BIO *out_bio = NULL; |
475 | 440 |
476 /* Build query object either from file or from scratch. */ 477 if (in != NULL) 478 { 479 if ((in_bio = BIO_new_file(in, "rb")) == NULL) goto end; 480 query = d2i_TS_REQ_bio(in_bio, NULL); 481 } 482 else 483 { 484 /* Open the file if no explicit digest bytes were specified. */ 485 if (!digest 486 && !(data_bio = BIO_open_with_default(data, "rb", stdin))) 487 goto end; 488 /* Creating the query object. */ 489 query = create_query(data_bio, digest, md, 490 policy, no_nonce, cert); 491 /* Saving the random number generator state. */ 492 } 493 if (query == NULL) goto end; | 441 /* Build query object either from file or from scratch. */ 442 if (in != NULL) { 443 if ((in_bio = BIO_new_file(in, "rb")) == NULL) 444 goto end; 445 query = d2i_TS_REQ_bio(in_bio, NULL); 446 } else { 447 /* 448 * Open the file if no explicit digest bytes were specified. 449 */ 450 if (!digest && !(data_bio = BIO_open_with_default(data, "rb", stdin))) 451 goto end; 452 /* Creating the query object. */ 453 query = create_query(data_bio, digest, md, policy, no_nonce, cert); 454 /* Saving the random number generator state. */ 455 } 456 if (query == NULL) 457 goto end; |
494 | 458 |
495 /* Write query either in ASN.1 or in text format. */ 496 if ((out_bio = BIO_open_with_default(out, "wb", stdout)) == NULL) 497 goto end; 498 if (text) 499 { 500 /* Text output. */ 501 if (!TS_REQ_print_bio(out_bio, query)) 502 goto end; 503 } 504 else 505 { 506 /* ASN.1 output. */ 507 if (!i2d_TS_REQ_bio(out_bio, query)) 508 goto end; 509 } | 459 /* Write query either in ASN.1 or in text format. */ 460 if ((out_bio = BIO_open_with_default(out, "wb", stdout)) == NULL) 461 goto end; 462 if (text) { 463 /* Text output. */ 464 if (!TS_REQ_print_bio(out_bio, query)) 465 goto end; 466 } else { 467 /* ASN.1 output. */ 468 if (!i2d_TS_REQ_bio(out_bio, query)) 469 goto end; 470 } |
510 | 471 |
511 ret = 1; | 472 ret = 1; |
512 513 end: | 473 474 end: |
514 ERR_print_errors(bio_err); | 475 ERR_print_errors(bio_err); |
515 | 476 |
516 /* Clean up. */ 517 BIO_free_all(in_bio); 518 BIO_free_all(data_bio); 519 BIO_free_all(out_bio); 520 TS_REQ_free(query); | 477 /* Clean up. */ 478 BIO_free_all(in_bio); 479 BIO_free_all(data_bio); 480 BIO_free_all(out_bio); 481 TS_REQ_free(query); |
521 | 482 |
522 return ret; 523 } | 483 return ret; 484} |
524 | 485 |
525static BIO *BIO_open_with_default(const char *file, const char *mode, 526 FILE *default_fp) 527 { 528 return file == NULL ? 529 BIO_new_fp(default_fp, BIO_NOCLOSE) 530 : BIO_new_file(file, mode); 531 } | 486static BIO *BIO_open_with_default(const char *file, const char *mode, 487 FILE *default_fp) 488{ 489 return file == NULL ? BIO_new_fp(default_fp, BIO_NOCLOSE) 490 : BIO_new_file(file, mode); 491} |
532 533static TS_REQ *create_query(BIO *data_bio, char *digest, const EVP_MD *md, | 492 493static TS_REQ *create_query(BIO *data_bio, char *digest, const EVP_MD *md, |
534 const char *policy, int no_nonce, int cert) 535 { 536 int ret = 0; 537 TS_REQ *ts_req = NULL; 538 int len; 539 TS_MSG_IMPRINT *msg_imprint = NULL; 540 X509_ALGOR *algo = NULL; 541 unsigned char *data = NULL; 542 ASN1_OBJECT *policy_obj = NULL; 543 ASN1_INTEGER *nonce_asn1 = NULL; | 494 const char *policy, int no_nonce, int cert) 495{ 496 int ret = 0; 497 TS_REQ *ts_req = NULL; 498 int len; 499 TS_MSG_IMPRINT *msg_imprint = NULL; 500 X509_ALGOR *algo = NULL; 501 unsigned char *data = NULL; 502 ASN1_OBJECT *policy_obj = NULL; 503 ASN1_INTEGER *nonce_asn1 = NULL; |
544 | 504 |
545 /* Setting default message digest. */ 546 if (!md && !(md = EVP_get_digestbyname("sha1"))) goto err; | 505 /* Setting default message digest. */ 506 if (!md && !(md = EVP_get_digestbyname("sha1"))) 507 goto err; |
547 | 508 |
548 /* Creating request object. */ 549 if (!(ts_req = TS_REQ_new())) goto err; | 509 /* Creating request object. */ 510 if (!(ts_req = TS_REQ_new())) 511 goto err; |
550 | 512 |
551 /* Setting version. */ 552 if (!TS_REQ_set_version(ts_req, 1)) goto err; | 513 /* Setting version. */ 514 if (!TS_REQ_set_version(ts_req, 1)) 515 goto err; |
553 | 516 |
554 /* Creating and adding MSG_IMPRINT object. */ 555 if (!(msg_imprint = TS_MSG_IMPRINT_new())) goto err; | 517 /* Creating and adding MSG_IMPRINT object. */ 518 if (!(msg_imprint = TS_MSG_IMPRINT_new())) 519 goto err; |
556 | 520 |
557 /* Adding algorithm. */ 558 if (!(algo = X509_ALGOR_new())) goto err; 559 if (!(algo->algorithm = OBJ_nid2obj(EVP_MD_type(md)))) goto err; 560 if (!(algo->parameter = ASN1_TYPE_new())) goto err; 561 algo->parameter->type = V_ASN1_NULL; 562 if (!TS_MSG_IMPRINT_set_algo(msg_imprint, algo)) goto err; | 521 /* Adding algorithm. */ 522 if (!(algo = X509_ALGOR_new())) 523 goto err; 524 if (!(algo->algorithm = OBJ_nid2obj(EVP_MD_type(md)))) 525 goto err; 526 if (!(algo->parameter = ASN1_TYPE_new())) 527 goto err; 528 algo->parameter->type = V_ASN1_NULL; 529 if (!TS_MSG_IMPRINT_set_algo(msg_imprint, algo)) 530 goto err; |
563 | 531 |
564 /* Adding message digest. */ 565 if ((len = create_digest(data_bio, digest, md, &data)) == 0) 566 goto err; 567 if (!TS_MSG_IMPRINT_set_msg(msg_imprint, data, len)) goto err; | 532 /* Adding message digest. */ 533 if ((len = create_digest(data_bio, digest, md, &data)) == 0) 534 goto err; 535 if (!TS_MSG_IMPRINT_set_msg(msg_imprint, data, len)) 536 goto err; |
568 | 537 |
569 if (!TS_REQ_set_msg_imprint(ts_req, msg_imprint)) goto err; 570 571 /* Setting policy if requested. */ 572 if (policy && !(policy_obj = txt2obj(policy))) goto err; 573 if (policy_obj && !TS_REQ_set_policy_id(ts_req, policy_obj)) goto err; | 538 if (!TS_REQ_set_msg_imprint(ts_req, msg_imprint)) 539 goto err; |
574 | 540 |
575 /* Setting nonce if requested. */ 576 if (!no_nonce && !(nonce_asn1 = create_nonce(NONCE_LENGTH))) goto err; 577 if (nonce_asn1 && !TS_REQ_set_nonce(ts_req, nonce_asn1)) goto err; | 541 /* Setting policy if requested. */ 542 if (policy && !(policy_obj = txt2obj(policy))) 543 goto err; 544 if (policy_obj && !TS_REQ_set_policy_id(ts_req, policy_obj)) 545 goto err; |
578 | 546 |
579 /* Setting certificate request flag if requested. */ 580 if (!TS_REQ_set_cert_req(ts_req, cert)) goto err; | 547 /* Setting nonce if requested. */ 548 if (!no_nonce && !(nonce_asn1 = create_nonce(NONCE_LENGTH))) 549 goto err; 550 if (nonce_asn1 && !TS_REQ_set_nonce(ts_req, nonce_asn1)) 551 goto err; |
581 | 552 |
582 ret = 1; | 553 /* Setting certificate request flag if requested. */ 554 if (!TS_REQ_set_cert_req(ts_req, cert)) 555 goto err; 556 557 ret = 1; |
583 err: | 558 err: |
584 if (!ret) 585 { 586 TS_REQ_free(ts_req); 587 ts_req = NULL; 588 BIO_printf(bio_err, "could not create query\n"); 589 } 590 TS_MSG_IMPRINT_free(msg_imprint); 591 X509_ALGOR_free(algo); 592 OPENSSL_free(data); 593 ASN1_OBJECT_free(policy_obj); 594 ASN1_INTEGER_free(nonce_asn1); 595 return ts_req; 596 } | 559 if (!ret) { 560 TS_REQ_free(ts_req); 561 ts_req = NULL; 562 BIO_printf(bio_err, "could not create query\n"); 563 } 564 TS_MSG_IMPRINT_free(msg_imprint); 565 X509_ALGOR_free(algo); 566 OPENSSL_free(data); 567 ASN1_OBJECT_free(policy_obj); 568 ASN1_INTEGER_free(nonce_asn1); 569 return ts_req; 570} |
597 598static int create_digest(BIO *input, char *digest, const EVP_MD *md, | 571 572static int create_digest(BIO *input, char *digest, const EVP_MD *md, |
599 unsigned char **md_value) 600 { 601 int md_value_len; | 573 unsigned char **md_value) 574{ 575 int md_value_len; |
602 | 576 |
603 md_value_len = EVP_MD_size(md); 604 if (md_value_len < 0) 605 goto err; 606 if (input) 607 { 608 /* Digest must be computed from an input file. */ 609 EVP_MD_CTX md_ctx; 610 unsigned char buffer[4096]; 611 int length; | 577 md_value_len = EVP_MD_size(md); 578 if (md_value_len < 0) 579 goto err; 580 if (input) { 581 /* Digest must be computed from an input file. */ 582 EVP_MD_CTX md_ctx; 583 unsigned char buffer[4096]; 584 int length; |
612 | 585 |
613 *md_value = OPENSSL_malloc(md_value_len); 614 if (*md_value == 0) goto err; | 586 *md_value = OPENSSL_malloc(md_value_len); 587 if (*md_value == 0) 588 goto err; |
615 | 589 |
616 EVP_DigestInit(&md_ctx, md); 617 while ((length = BIO_read(input, buffer, sizeof(buffer))) > 0) 618 { 619 EVP_DigestUpdate(&md_ctx, buffer, length); 620 } 621 EVP_DigestFinal(&md_ctx, *md_value, NULL); 622 } 623 else 624 { 625 /* Digest bytes are specified with digest. */ 626 long digest_len; 627 *md_value = string_to_hex(digest, &digest_len); 628 if (!*md_value || md_value_len != digest_len) 629 { 630 OPENSSL_free(*md_value); 631 *md_value = NULL; 632 BIO_printf(bio_err, "bad digest, %d bytes " 633 "must be specified\n", md_value_len); 634 goto err; 635 } 636 } | 590 EVP_DigestInit(&md_ctx, md); 591 while ((length = BIO_read(input, buffer, sizeof(buffer))) > 0) { 592 EVP_DigestUpdate(&md_ctx, buffer, length); 593 } 594 EVP_DigestFinal(&md_ctx, *md_value, NULL); 595 } else { 596 /* Digest bytes are specified with digest. */ 597 long digest_len; 598 *md_value = string_to_hex(digest, &digest_len); 599 if (!*md_value || md_value_len != digest_len) { 600 OPENSSL_free(*md_value); 601 *md_value = NULL; 602 BIO_printf(bio_err, "bad digest, %d bytes " 603 "must be specified\n", md_value_len); 604 goto err; 605 } 606 } |
637 | 607 |
638 return md_value_len; | 608 return md_value_len; |
639 err: | 609 err: |
640 return 0; 641 } | 610 return 0; 611} |
642 643static ASN1_INTEGER *create_nonce(int bits) | 612 613static ASN1_INTEGER *create_nonce(int bits) |
644 { 645 unsigned char buf[20]; 646 ASN1_INTEGER *nonce = NULL; 647 int len = (bits - 1) / 8 + 1; 648 int i; | 614{ 615 unsigned char buf[20]; 616 ASN1_INTEGER *nonce = NULL; 617 int len = (bits - 1) / 8 + 1; 618 int i; |
649 | 619 |
650 /* Generating random byte sequence. */ 651 if (len > (int)sizeof(buf)) goto err; 652 if (RAND_bytes(buf, len) <= 0) goto err; | 620 /* Generating random byte sequence. */ 621 if (len > (int)sizeof(buf)) 622 goto err; 623 if (RAND_bytes(buf, len) <= 0) 624 goto err; |
653 | 625 |
654 /* Find the first non-zero byte and creating ASN1_INTEGER object. */ 655 for (i = 0; i < len && !buf[i]; ++i); 656 if (!(nonce = ASN1_INTEGER_new())) goto err; 657 OPENSSL_free(nonce->data); 658 /* Allocate at least one byte. */ 659 nonce->length = len - i; 660 if (!(nonce->data = OPENSSL_malloc(nonce->length + 1))) goto err; 661 memcpy(nonce->data, buf + i, nonce->length); | 626 /* Find the first non-zero byte and creating ASN1_INTEGER object. */ 627 for (i = 0; i < len && !buf[i]; ++i) ; 628 if (!(nonce = ASN1_INTEGER_new())) 629 goto err; 630 OPENSSL_free(nonce->data); 631 /* Allocate at least one byte. */ 632 nonce->length = len - i; 633 if (!(nonce->data = OPENSSL_malloc(nonce->length + 1))) 634 goto err; 635 memcpy(nonce->data, buf + i, nonce->length); |
662 | 636 |
663 return nonce; | 637 return nonce; |
664 err: | 638 err: |
665 BIO_printf(bio_err, "could not create nonce\n"); 666 ASN1_INTEGER_free(nonce); 667 return NULL; 668 } | 639 BIO_printf(bio_err, "could not create nonce\n"); 640 ASN1_INTEGER_free(nonce); 641 return NULL; 642} 643 |
669/* 670 * Reply-related method definitions. 671 */ 672 | 644/* 645 * Reply-related method definitions. 646 */ 647 |
673static int reply_command(CONF *conf, char *section, char *engine, 674 char *queryfile, char *passin, char *inkey, 675 char *signer, char *chain, const char *policy, 676 char *in, int token_in, 677 char *out, int token_out, int text) 678 { 679 int ret = 0; 680 TS_RESP *response = NULL; 681 BIO *in_bio = NULL; 682 BIO *query_bio = NULL; 683 BIO *inkey_bio = NULL; 684 BIO *signer_bio = NULL; 685 BIO *out_bio = NULL; | 648static int reply_command(CONF *conf, char *section, char *engine, 649 char *queryfile, char *passin, char *inkey, 650 char *signer, char *chain, const char *policy, 651 char *in, int token_in, 652 char *out, int token_out, int text) 653{ 654 int ret = 0; 655 TS_RESP *response = NULL; 656 BIO *in_bio = NULL; 657 BIO *query_bio = NULL; 658 BIO *inkey_bio = NULL; 659 BIO *signer_bio = NULL; 660 BIO *out_bio = NULL; |
686 | 661 |
687 /* Build response object either from response or query. */ 688 if (in != NULL) 689 { 690 if ((in_bio = BIO_new_file(in, "rb")) == NULL) goto end; 691 if (token_in) 692 { 693 /* We have a ContentInfo (PKCS7) object, add 694 'granted' status info around it. */ 695 response = read_PKCS7(in_bio); 696 } 697 else 698 { 699 /* We have a ready-made TS_RESP object. */ 700 response = d2i_TS_RESP_bio(in_bio, NULL); 701 } 702 } 703 else 704 { 705 response = create_response(conf, section, engine, queryfile, 706 passin, inkey, signer, chain, 707 policy); 708 if (response) 709 BIO_printf(bio_err, "Response has been generated.\n"); 710 else 711 BIO_printf(bio_err, "Response is not generated.\n"); 712 } 713 if (response == NULL) goto end; | 662 /* Build response object either from response or query. */ 663 if (in != NULL) { 664 if ((in_bio = BIO_new_file(in, "rb")) == NULL) 665 goto end; 666 if (token_in) { 667 /* 668 * We have a ContentInfo (PKCS7) object, add 'granted' status 669 * info around it. 670 */ 671 response = read_PKCS7(in_bio); 672 } else { 673 /* We have a ready-made TS_RESP object. */ 674 response = d2i_TS_RESP_bio(in_bio, NULL); 675 } 676 } else { 677 response = create_response(conf, section, engine, queryfile, 678 passin, inkey, signer, chain, policy); 679 if (response) 680 BIO_printf(bio_err, "Response has been generated.\n"); 681 else 682 BIO_printf(bio_err, "Response is not generated.\n"); 683 } 684 if (response == NULL) 685 goto end; |
714 | 686 |
715 /* Write response either in ASN.1 or text format. */ 716 if ((out_bio = BIO_open_with_default(out, "wb", stdout)) == NULL) 717 goto end; 718 if (text) 719 { 720 /* Text output. */ 721 if (token_out) 722 { 723 TS_TST_INFO *tst_info = TS_RESP_get_tst_info(response); 724 if (!TS_TST_INFO_print_bio(out_bio, tst_info)) goto end; 725 } 726 else 727 { 728 if (!TS_RESP_print_bio(out_bio, response)) goto end; 729 } 730 } 731 else 732 { 733 /* ASN.1 DER output. */ 734 if (token_out) 735 { 736 PKCS7 *token = TS_RESP_get_token(response); 737 if (!i2d_PKCS7_bio(out_bio, token)) goto end; 738 } 739 else 740 { 741 if (!i2d_TS_RESP_bio(out_bio, response)) goto end; 742 } 743 } | 687 /* Write response either in ASN.1 or text format. */ 688 if ((out_bio = BIO_open_with_default(out, "wb", stdout)) == NULL) 689 goto end; 690 if (text) { 691 /* Text output. */ 692 if (token_out) { 693 TS_TST_INFO *tst_info = TS_RESP_get_tst_info(response); 694 if (!TS_TST_INFO_print_bio(out_bio, tst_info)) 695 goto end; 696 } else { 697 if (!TS_RESP_print_bio(out_bio, response)) 698 goto end; 699 } 700 } else { 701 /* ASN.1 DER output. */ 702 if (token_out) { 703 PKCS7 *token = TS_RESP_get_token(response); 704 if (!i2d_PKCS7_bio(out_bio, token)) 705 goto end; 706 } else { 707 if (!i2d_TS_RESP_bio(out_bio, response)) 708 goto end; 709 } 710 } |
744 | 711 |
745 ret = 1; | 712 ret = 1; |
746 747 end: | 713 714 end: |
748 ERR_print_errors(bio_err); | 715 ERR_print_errors(bio_err); |
749 | 716 |
750 /* Clean up. */ 751 BIO_free_all(in_bio); 752 BIO_free_all(query_bio); 753 BIO_free_all(inkey_bio); 754 BIO_free_all(signer_bio); 755 BIO_free_all(out_bio); 756 TS_RESP_free(response); | 717 /* Clean up. */ 718 BIO_free_all(in_bio); 719 BIO_free_all(query_bio); 720 BIO_free_all(inkey_bio); 721 BIO_free_all(signer_bio); 722 BIO_free_all(out_bio); 723 TS_RESP_free(response); |
757 | 724 |
758 return ret; 759 } | 725 return ret; 726} |
760 761/* Reads a PKCS7 token and adds default 'granted' status info to it. */ 762static TS_RESP *read_PKCS7(BIO *in_bio) | 727 728/* Reads a PKCS7 token and adds default 'granted' status info to it. */ 729static TS_RESP *read_PKCS7(BIO *in_bio) |
763 { 764 int ret = 0; 765 PKCS7 *token = NULL; 766 TS_TST_INFO *tst_info = NULL; 767 TS_RESP *resp = NULL; 768 TS_STATUS_INFO *si = NULL; | 730{ 731 int ret = 0; 732 PKCS7 *token = NULL; 733 TS_TST_INFO *tst_info = NULL; 734 TS_RESP *resp = NULL; 735 TS_STATUS_INFO *si = NULL; |
769 | 736 |
770 /* Read PKCS7 object and extract the signed time stamp info. */ 771 if (!(token = d2i_PKCS7_bio(in_bio, NULL))) goto end; 772 if (!(tst_info = PKCS7_to_TS_TST_INFO(token))) goto end; | 737 /* Read PKCS7 object and extract the signed time stamp info. */ 738 if (!(token = d2i_PKCS7_bio(in_bio, NULL))) 739 goto end; 740 if (!(tst_info = PKCS7_to_TS_TST_INFO(token))) 741 goto end; |
773 | 742 |
774 /* Creating response object. */ 775 if (!(resp = TS_RESP_new())) goto end; | 743 /* Creating response object. */ 744 if (!(resp = TS_RESP_new())) 745 goto end; |
776 | 746 |
777 /* Create granted status info. */ 778 if (!(si = TS_STATUS_INFO_new())) goto end; 779 if (!(ASN1_INTEGER_set(si->status, TS_STATUS_GRANTED))) goto end; 780 if (!TS_RESP_set_status_info(resp, si)) goto end; | 747 /* Create granted status info. */ 748 if (!(si = TS_STATUS_INFO_new())) 749 goto end; 750 if (!(ASN1_INTEGER_set(si->status, TS_STATUS_GRANTED))) 751 goto end; 752 if (!TS_RESP_set_status_info(resp, si)) 753 goto end; |
781 | 754 |
782 /* Setting encapsulated token. */ 783 TS_RESP_set_tst_info(resp, token, tst_info); 784 token = NULL; /* Ownership is lost. */ 785 tst_info = NULL; /* Ownership is lost. */ | 755 /* Setting encapsulated token. */ 756 TS_RESP_set_tst_info(resp, token, tst_info); 757 token = NULL; /* Ownership is lost. */ 758 tst_info = NULL; /* Ownership is lost. */ |
786 | 759 |
787 ret = 1; | 760 ret = 1; |
788 end: | 761 end: |
789 PKCS7_free(token); 790 TS_TST_INFO_free(tst_info); 791 if (!ret) 792 { 793 TS_RESP_free(resp); 794 resp = NULL; 795 } 796 TS_STATUS_INFO_free(si); 797 return resp; 798 } | 762 PKCS7_free(token); 763 TS_TST_INFO_free(tst_info); 764 if (!ret) { 765 TS_RESP_free(resp); 766 resp = NULL; 767 } 768 TS_STATUS_INFO_free(si); 769 return resp; 770} |
799 | 771 |
800static TS_RESP *create_response(CONF *conf, const char *section, char *engine, 801 char *queryfile, char *passin, char *inkey, 802 char *signer, char *chain, const char *policy) 803 { 804 int ret = 0; 805 TS_RESP *response = NULL; 806 BIO *query_bio = NULL; 807 TS_RESP_CTX *resp_ctx = NULL; | 772static TS_RESP *create_response(CONF *conf, const char *section, char *engine, 773 char *queryfile, char *passin, char *inkey, 774 char *signer, char *chain, const char *policy) 775{ 776 int ret = 0; 777 TS_RESP *response = NULL; 778 BIO *query_bio = NULL; 779 TS_RESP_CTX *resp_ctx = NULL; |
808 | 780 |
809 if (!(query_bio = BIO_new_file(queryfile, "rb"))) 810 goto end; | 781 if (!(query_bio = BIO_new_file(queryfile, "rb"))) 782 goto end; |
811 | 783 |
812 /* Getting TSA configuration section. */ 813 if (!(section = TS_CONF_get_tsa_section(conf, section))) 814 goto end; | 784 /* Getting TSA configuration section. */ 785 if (!(section = TS_CONF_get_tsa_section(conf, section))) 786 goto end; |
815 | 787 |
816 /* Setting up response generation context. */ 817 if (!(resp_ctx = TS_RESP_CTX_new())) goto end; | 788 /* Setting up response generation context. */ 789 if (!(resp_ctx = TS_RESP_CTX_new())) 790 goto end; |
818 | 791 |
819 /* Setting serial number provider callback. */ 820 if (!TS_CONF_set_serial(conf, section, serial_cb, resp_ctx)) goto end; | 792 /* Setting serial number provider callback. */ 793 if (!TS_CONF_set_serial(conf, section, serial_cb, resp_ctx)) 794 goto end; |
821#ifndef OPENSSL_NO_ENGINE | 795#ifndef OPENSSL_NO_ENGINE |
822 /* Setting default OpenSSL engine. */ 823 if (!TS_CONF_set_crypto_device(conf, section, engine)) goto end; | 796 /* Setting default OpenSSL engine. */ 797 if (!TS_CONF_set_crypto_device(conf, section, engine)) 798 goto end; |
824#endif 825 | 799#endif 800 |
826 /* Setting TSA signer certificate. */ 827 if (!TS_CONF_set_signer_cert(conf, section, signer, resp_ctx)) goto end; | 801 /* Setting TSA signer certificate. */ 802 if (!TS_CONF_set_signer_cert(conf, section, signer, resp_ctx)) 803 goto end; |
828 | 804 |
829 /* Setting TSA signer certificate chain. */ 830 if (!TS_CONF_set_certs(conf, section, chain, resp_ctx)) goto end; | 805 /* Setting TSA signer certificate chain. */ 806 if (!TS_CONF_set_certs(conf, section, chain, resp_ctx)) 807 goto end; |
831 | 808 |
832 /* Setting TSA signer private key. */ 833 if (!TS_CONF_set_signer_key(conf, section, inkey, passin, resp_ctx)) 834 goto end; | 809 /* Setting TSA signer private key. */ 810 if (!TS_CONF_set_signer_key(conf, section, inkey, passin, resp_ctx)) 811 goto end; |
835 | 812 |
836 /* Setting default policy OID. */ 837 if (!TS_CONF_set_def_policy(conf, section, policy, resp_ctx)) goto end; | 813 /* Setting default policy OID. */ 814 if (!TS_CONF_set_def_policy(conf, section, policy, resp_ctx)) 815 goto end; |
838 | 816 |
839 /* Setting acceptable policy OIDs. */ 840 if (!TS_CONF_set_policies(conf, section, resp_ctx)) goto end; | 817 /* Setting acceptable policy OIDs. */ 818 if (!TS_CONF_set_policies(conf, section, resp_ctx)) 819 goto end; |
841 | 820 |
842 /* Setting the acceptable one-way hash algorithms. */ 843 if (!TS_CONF_set_digests(conf, section, resp_ctx)) goto end; | 821 /* Setting the acceptable one-way hash algorithms. */ 822 if (!TS_CONF_set_digests(conf, section, resp_ctx)) 823 goto end; |
844 | 824 |
845 /* Setting guaranteed time stamp accuracy. */ 846 if (!TS_CONF_set_accuracy(conf, section, resp_ctx)) goto end; | 825 /* Setting guaranteed time stamp accuracy. */ 826 if (!TS_CONF_set_accuracy(conf, section, resp_ctx)) 827 goto end; |
847 | 828 |
848 /* Setting the precision of the time. */ 849 if (!TS_CONF_set_clock_precision_digits(conf, section, resp_ctx)) 850 goto end; | 829 /* Setting the precision of the time. */ 830 if (!TS_CONF_set_clock_precision_digits(conf, section, resp_ctx)) 831 goto end; |
851 | 832 |
852 /* Setting the ordering flaf if requested. */ 853 if (!TS_CONF_set_ordering(conf, section, resp_ctx)) goto end; | 833 /* Setting the ordering flaf if requested. */ 834 if (!TS_CONF_set_ordering(conf, section, resp_ctx)) 835 goto end; |
854 | 836 |
855 /* Setting the TSA name required flag if requested. */ 856 if (!TS_CONF_set_tsa_name(conf, section, resp_ctx)) goto end; | 837 /* Setting the TSA name required flag if requested. */ 838 if (!TS_CONF_set_tsa_name(conf, section, resp_ctx)) 839 goto end; |
857 | 840 |
858 /* Setting the ESS cert id chain flag if requested. */ 859 if (!TS_CONF_set_ess_cert_id_chain(conf, section, resp_ctx)) goto end; | 841 /* Setting the ESS cert id chain flag if requested. */ 842 if (!TS_CONF_set_ess_cert_id_chain(conf, section, resp_ctx)) 843 goto end; |
860 | 844 |
861 /* Creating the response. */ 862 if (!(response = TS_RESP_create_response(resp_ctx, query_bio))) 863 goto end; | 845 /* Creating the response. */ 846 if (!(response = TS_RESP_create_response(resp_ctx, query_bio))) 847 goto end; |
864 | 848 |
865 ret = 1; | 849 ret = 1; |
866 end: | 850 end: |
867 if (!ret) 868 { 869 TS_RESP_free(response); 870 response = NULL; 871 } 872 TS_RESP_CTX_free(resp_ctx); 873 BIO_free_all(query_bio); | 851 if (!ret) { 852 TS_RESP_free(response); 853 response = NULL; 854 } 855 TS_RESP_CTX_free(resp_ctx); 856 BIO_free_all(query_bio); |
874 | 857 |
875 return response; 876 } | 858 return response; 859} |
877 | 860 |
878static ASN1_INTEGER * MS_CALLBACK serial_cb(TS_RESP_CTX *ctx, void *data) 879 { 880 const char *serial_file = (const char *) data; 881 ASN1_INTEGER *serial = next_serial(serial_file); | 861static ASN1_INTEGER *MS_CALLBACK serial_cb(TS_RESP_CTX *ctx, void *data) 862{ 863 const char *serial_file = (const char *)data; 864 ASN1_INTEGER *serial = next_serial(serial_file); |
882 | 865 |
883 if (!serial) 884 { 885 TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, 886 "Error during serial number " 887 "generation."); 888 TS_RESP_CTX_add_failure_info(ctx, 889 TS_INFO_ADD_INFO_NOT_AVAILABLE); 890 } 891 else 892 save_ts_serial(serial_file, serial); | 866 if (!serial) { 867 TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, 868 "Error during serial number " 869 "generation."); 870 TS_RESP_CTX_add_failure_info(ctx, TS_INFO_ADD_INFO_NOT_AVAILABLE); 871 } else 872 save_ts_serial(serial_file, serial); |
893 | 873 |
894 return serial; 895 } | 874 return serial; 875} |
896 897static ASN1_INTEGER *next_serial(const char *serialfile) | 876 877static ASN1_INTEGER *next_serial(const char *serialfile) |
898 { 899 int ret = 0; 900 BIO *in = NULL; 901 ASN1_INTEGER *serial = NULL; 902 BIGNUM *bn = NULL; | 878{ 879 int ret = 0; 880 BIO *in = NULL; 881 ASN1_INTEGER *serial = NULL; 882 BIGNUM *bn = NULL; |
903 | 883 |
904 if (!(serial = ASN1_INTEGER_new())) goto err; | 884 if (!(serial = ASN1_INTEGER_new())) 885 goto err; |
905 | 886 |
906 if (!(in = BIO_new_file(serialfile, "r"))) 907 { 908 ERR_clear_error(); 909 BIO_printf(bio_err, "Warning: could not open file %s for " 910 "reading, using serial number: 1\n", serialfile); 911 if (!ASN1_INTEGER_set(serial, 1)) goto err; 912 } 913 else 914 { 915 char buf[1024]; 916 if (!a2i_ASN1_INTEGER(in, serial, buf, sizeof(buf))) 917 { 918 BIO_printf(bio_err, "unable to load number from %s\n", 919 serialfile); 920 goto err; 921 } 922 if (!(bn = ASN1_INTEGER_to_BN(serial, NULL))) goto err; 923 ASN1_INTEGER_free(serial); 924 serial = NULL; 925 if (!BN_add_word(bn, 1)) goto err; 926 if (!(serial = BN_to_ASN1_INTEGER(bn, NULL))) goto err; 927 } 928 ret = 1; | 887 if (!(in = BIO_new_file(serialfile, "r"))) { 888 ERR_clear_error(); 889 BIO_printf(bio_err, "Warning: could not open file %s for " 890 "reading, using serial number: 1\n", serialfile); 891 if (!ASN1_INTEGER_set(serial, 1)) 892 goto err; 893 } else { 894 char buf[1024]; 895 if (!a2i_ASN1_INTEGER(in, serial, buf, sizeof(buf))) { 896 BIO_printf(bio_err, "unable to load number from %s\n", 897 serialfile); 898 goto err; 899 } 900 if (!(bn = ASN1_INTEGER_to_BN(serial, NULL))) 901 goto err; 902 ASN1_INTEGER_free(serial); 903 serial = NULL; 904 if (!BN_add_word(bn, 1)) 905 goto err; 906 if (!(serial = BN_to_ASN1_INTEGER(bn, NULL))) 907 goto err; 908 } 909 ret = 1; |
929 err: | 910 err: |
930 if (!ret) 931 { 932 ASN1_INTEGER_free(serial); 933 serial = NULL; 934 } 935 BIO_free_all(in); 936 BN_free(bn); 937 return serial; 938 } | 911 if (!ret) { 912 ASN1_INTEGER_free(serial); 913 serial = NULL; 914 } 915 BIO_free_all(in); 916 BN_free(bn); 917 return serial; 918} |
939 940static int save_ts_serial(const char *serialfile, ASN1_INTEGER *serial) | 919 920static int save_ts_serial(const char *serialfile, ASN1_INTEGER *serial) |
941 { 942 int ret = 0; 943 BIO *out = NULL; | 921{ 922 int ret = 0; 923 BIO *out = NULL; |
944 | 924 |
945 if (!(out = BIO_new_file(serialfile, "w"))) goto err; 946 if (i2a_ASN1_INTEGER(out, serial) <= 0) goto err; 947 if (BIO_puts(out, "\n") <= 0) goto err; 948 ret = 1; | 925 if (!(out = BIO_new_file(serialfile, "w"))) 926 goto err; 927 if (i2a_ASN1_INTEGER(out, serial) <= 0) 928 goto err; 929 if (BIO_puts(out, "\n") <= 0) 930 goto err; 931 ret = 1; |
949 err: | 932 err: |
950 if (!ret) 951 BIO_printf(bio_err, "could not save serial number to %s\n", 952 serialfile); 953 BIO_free_all(out); 954 return ret; 955 } | 933 if (!ret) 934 BIO_printf(bio_err, "could not save serial number to %s\n", 935 serialfile); 936 BIO_free_all(out); 937 return ret; 938} |
956 957/* 958 * Verify-related method definitions. 959 */ 960 961static int verify_command(char *data, char *digest, char *queryfile, | 939 940/* 941 * Verify-related method definitions. 942 */ 943 944static int verify_command(char *data, char *digest, char *queryfile, |
962 char *in, int token_in, 963 char *ca_path, char *ca_file, char *untrusted) 964 { 965 BIO *in_bio = NULL; 966 PKCS7 *token = NULL; 967 TS_RESP *response = NULL; 968 TS_VERIFY_CTX *verify_ctx = NULL; 969 int ret = 0; | 945 char *in, int token_in, 946 char *ca_path, char *ca_file, char *untrusted) 947{ 948 BIO *in_bio = NULL; 949 PKCS7 *token = NULL; 950 TS_RESP *response = NULL; 951 TS_VERIFY_CTX *verify_ctx = NULL; 952 int ret = 0; |
970 | 953 |
971 /* Decode the token (PKCS7) or response (TS_RESP) files. */ 972 if (!(in_bio = BIO_new_file(in, "rb"))) goto end; 973 if (token_in) 974 { 975 if (!(token = d2i_PKCS7_bio(in_bio, NULL))) goto end; 976 } 977 else 978 { 979 if (!(response = d2i_TS_RESP_bio(in_bio, NULL))) goto end; 980 } | 954 /* Decode the token (PKCS7) or response (TS_RESP) files. */ 955 if (!(in_bio = BIO_new_file(in, "rb"))) 956 goto end; 957 if (token_in) { 958 if (!(token = d2i_PKCS7_bio(in_bio, NULL))) 959 goto end; 960 } else { 961 if (!(response = d2i_TS_RESP_bio(in_bio, NULL))) 962 goto end; 963 } |
981 | 964 |
982 if (!(verify_ctx = create_verify_ctx(data, digest, queryfile, 983 ca_path, ca_file, untrusted))) 984 goto end; | 965 if (!(verify_ctx = create_verify_ctx(data, digest, queryfile, 966 ca_path, ca_file, untrusted))) 967 goto end; |
985 | 968 |
986 /* Checking the token or response against the request. */ 987 ret = token_in ? 988 TS_RESP_verify_token(verify_ctx, token) : 989 TS_RESP_verify_response(verify_ctx, response); | 969 /* Checking the token or response against the request. */ 970 ret = token_in ? 971 TS_RESP_verify_token(verify_ctx, token) : 972 TS_RESP_verify_response(verify_ctx, response); |
990 991 end: | 973 974 end: |
992 printf("Verification: "); 993 if (ret) 994 printf("OK\n"); 995 else 996 { 997 printf("FAILED\n"); 998 /* Print errors, if there are any. */ 999 ERR_print_errors(bio_err); 1000 } 1001 1002 /* Clean up. */ 1003 BIO_free_all(in_bio); 1004 PKCS7_free(token); 1005 TS_RESP_free(response); 1006 TS_VERIFY_CTX_free(verify_ctx); 1007 return ret; 1008 } | 975 printf("Verification: "); 976 if (ret) 977 printf("OK\n"); 978 else { 979 printf("FAILED\n"); 980 /* Print errors, if there are any. */ 981 ERR_print_errors(bio_err); 982 } |
1009 | 983 |
1010static TS_VERIFY_CTX *create_verify_ctx(char *data, char *digest, 1011 char *queryfile, 1012 char *ca_path, char *ca_file, 1013 char *untrusted) 1014 { 1015 TS_VERIFY_CTX *ctx = NULL; 1016 BIO *input = NULL; 1017 TS_REQ *request = NULL; 1018 int ret = 0; | 984 /* Clean up. */ 985 BIO_free_all(in_bio); 986 PKCS7_free(token); 987 TS_RESP_free(response); 988 TS_VERIFY_CTX_free(verify_ctx); 989 return ret; 990} |
1019 | 991 |
1020 if (data != NULL || digest != NULL) 1021 { 1022 if (!(ctx = TS_VERIFY_CTX_new())) goto err; 1023 ctx->flags = TS_VFY_VERSION | TS_VFY_SIGNER; 1024 if (data != NULL) 1025 { 1026 ctx->flags |= TS_VFY_DATA; 1027 if (!(ctx->data = BIO_new_file(data, "rb"))) goto err; 1028 } 1029 else if (digest != NULL) 1030 { 1031 long imprint_len; 1032 ctx->flags |= TS_VFY_IMPRINT; 1033 if (!(ctx->imprint = string_to_hex(digest, 1034 &imprint_len))) 1035 { 1036 BIO_printf(bio_err, "invalid digest string\n"); 1037 goto err; 1038 } 1039 ctx->imprint_len = imprint_len; 1040 } 1041 1042 } 1043 else if (queryfile != NULL) 1044 { 1045 /* The request has just to be read, decoded and converted to 1046 a verify context object. */ 1047 if (!(input = BIO_new_file(queryfile, "rb"))) goto err; 1048 if (!(request = d2i_TS_REQ_bio(input, NULL))) goto err; 1049 if (!(ctx = TS_REQ_to_TS_VERIFY_CTX(request, NULL))) goto err; 1050 } 1051 else 1052 return NULL; | 992static TS_VERIFY_CTX *create_verify_ctx(char *data, char *digest, 993 char *queryfile, 994 char *ca_path, char *ca_file, 995 char *untrusted) 996{ 997 TS_VERIFY_CTX *ctx = NULL; 998 BIO *input = NULL; 999 TS_REQ *request = NULL; 1000 int ret = 0; |
1053 | 1001 |
1054 /* Add the signature verification flag and arguments. */ 1055 ctx->flags |= TS_VFY_SIGNATURE; | 1002 if (data != NULL || digest != NULL) { 1003 if (!(ctx = TS_VERIFY_CTX_new())) 1004 goto err; 1005 ctx->flags = TS_VFY_VERSION | TS_VFY_SIGNER; 1006 if (data != NULL) { 1007 ctx->flags |= TS_VFY_DATA; 1008 if (!(ctx->data = BIO_new_file(data, "rb"))) 1009 goto err; 1010 } else if (digest != NULL) { 1011 long imprint_len; 1012 ctx->flags |= TS_VFY_IMPRINT; 1013 if (!(ctx->imprint = string_to_hex(digest, &imprint_len))) { 1014 BIO_printf(bio_err, "invalid digest string\n"); 1015 goto err; 1016 } 1017 ctx->imprint_len = imprint_len; 1018 } |
1056 | 1019 |
1057 /* Initialising the X509_STORE object. */ 1058 if (!(ctx->store = create_cert_store(ca_path, ca_file))) goto err; | 1020 } else if (queryfile != NULL) { 1021 /* 1022 * The request has just to be read, decoded and converted to a verify 1023 * context object. 1024 */ 1025 if (!(input = BIO_new_file(queryfile, "rb"))) 1026 goto err; 1027 if (!(request = d2i_TS_REQ_bio(input, NULL))) 1028 goto err; 1029 if (!(ctx = TS_REQ_to_TS_VERIFY_CTX(request, NULL))) 1030 goto err; 1031 } else 1032 return NULL; |
1059 | 1033 |
1060 /* Loading untrusted certificates. */ 1061 if (untrusted && !(ctx->certs = TS_CONF_load_certs(untrusted))) 1062 goto err; | 1034 /* Add the signature verification flag and arguments. */ 1035 ctx->flags |= TS_VFY_SIGNATURE; |
1063 | 1036 |
1064 ret = 1; | 1037 /* Initialising the X509_STORE object. */ 1038 if (!(ctx->store = create_cert_store(ca_path, ca_file))) 1039 goto err; 1040 1041 /* Loading untrusted certificates. */ 1042 if (untrusted && !(ctx->certs = TS_CONF_load_certs(untrusted))) 1043 goto err; 1044 1045 ret = 1; |
1065 err: | 1046 err: |
1066 if (!ret) 1067 { 1068 TS_VERIFY_CTX_free(ctx); 1069 ctx = NULL; 1070 } 1071 BIO_free_all(input); 1072 TS_REQ_free(request); 1073 return ctx; 1074 } | 1047 if (!ret) { 1048 TS_VERIFY_CTX_free(ctx); 1049 ctx = NULL; 1050 } 1051 BIO_free_all(input); 1052 TS_REQ_free(request); 1053 return ctx; 1054} |
1075 1076static X509_STORE *create_cert_store(char *ca_path, char *ca_file) | 1055 1056static X509_STORE *create_cert_store(char *ca_path, char *ca_file) |
1077 { 1078 X509_STORE *cert_ctx = NULL; 1079 X509_LOOKUP *lookup = NULL; 1080 int i; | 1057{ 1058 X509_STORE *cert_ctx = NULL; 1059 X509_LOOKUP *lookup = NULL; 1060 int i; |
1081 | 1061 |
1082 /* Creating the X509_STORE object. */ 1083 cert_ctx = X509_STORE_new(); | 1062 /* Creating the X509_STORE object. */ 1063 cert_ctx = X509_STORE_new(); |
1084 | 1064 |
1085 /* Setting the callback for certificate chain verification. */ 1086 X509_STORE_set_verify_cb(cert_ctx, verify_cb); | 1065 /* Setting the callback for certificate chain verification. */ 1066 X509_STORE_set_verify_cb(cert_ctx, verify_cb); |
1087 | 1067 |
1088 /* Adding a trusted certificate directory source. */ 1089 if (ca_path) 1090 { 1091 lookup = X509_STORE_add_lookup(cert_ctx, 1092 X509_LOOKUP_hash_dir()); 1093 if (lookup == NULL) 1094 { 1095 BIO_printf(bio_err, "memory allocation failure\n"); 1096 goto err; 1097 } 1098 i = X509_LOOKUP_add_dir(lookup, ca_path, X509_FILETYPE_PEM); 1099 if (!i) 1100 { 1101 BIO_printf(bio_err, "Error loading directory %s\n", 1102 ca_path); 1103 goto err; 1104 } 1105 } | 1068 /* Adding a trusted certificate directory source. */ 1069 if (ca_path) { 1070 lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_hash_dir()); 1071 if (lookup == NULL) { 1072 BIO_printf(bio_err, "memory allocation failure\n"); 1073 goto err; 1074 } 1075 i = X509_LOOKUP_add_dir(lookup, ca_path, X509_FILETYPE_PEM); 1076 if (!i) { 1077 BIO_printf(bio_err, "Error loading directory %s\n", ca_path); 1078 goto err; 1079 } 1080 } |
1106 | 1081 |
1107 /* Adding a trusted certificate file source. */ 1108 if (ca_file) 1109 { 1110 lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_file()); 1111 if (lookup == NULL) 1112 { 1113 BIO_printf(bio_err, "memory allocation failure\n"); 1114 goto err; 1115 } 1116 i = X509_LOOKUP_load_file(lookup, ca_file, X509_FILETYPE_PEM); 1117 if (!i) 1118 { 1119 BIO_printf(bio_err, "Error loading file %s\n", ca_file); 1120 goto err; 1121 } 1122 } | 1082 /* Adding a trusted certificate file source. */ 1083 if (ca_file) { 1084 lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_file()); 1085 if (lookup == NULL) { 1086 BIO_printf(bio_err, "memory allocation failure\n"); 1087 goto err; 1088 } 1089 i = X509_LOOKUP_load_file(lookup, ca_file, X509_FILETYPE_PEM); 1090 if (!i) { 1091 BIO_printf(bio_err, "Error loading file %s\n", ca_file); 1092 goto err; 1093 } 1094 } |
1123 | 1095 |
1124 return cert_ctx; | 1096 return cert_ctx; |
1125 err: | 1097 err: |
1126 X509_STORE_free(cert_ctx); 1127 return NULL; 1128 } | 1098 X509_STORE_free(cert_ctx); 1099 return NULL; 1100} |
1129 1130static int MS_CALLBACK verify_cb(int ok, X509_STORE_CTX *ctx) | 1101 1102static int MS_CALLBACK verify_cb(int ok, X509_STORE_CTX *ctx) |
1131 { 1132 /* 1133 char buf[256]; | 1103{ 1104 /*- 1105 char buf[256]; |
1134 | 1106 |
1135 if (!ok) 1136 { 1137 X509_NAME_oneline(X509_get_subject_name(ctx->current_cert), 1138 buf, sizeof(buf)); 1139 printf("%s\n", buf); 1140 printf("error %d at %d depth lookup: %s\n", 1141 ctx->error, ctx->error_depth, 1142 X509_verify_cert_error_string(ctx->error)); 1143 } 1144 */ | 1107 if (!ok) 1108 { 1109 X509_NAME_oneline(X509_get_subject_name(ctx->current_cert), 1110 buf, sizeof(buf)); 1111 printf("%s\n", buf); 1112 printf("error %d at %d depth lookup: %s\n", 1113 ctx->error, ctx->error_depth, 1114 X509_verify_cert_error_string(ctx->error)); 1115 } 1116 */ |
1145 | 1117 |
1146 return ok; 1147 } | 1118 return ok; 1119} |