EAC_CTX * EAC_CTX_new(void) { EAC_CTX *ctx = OPENSSL_malloc(sizeof(EAC_CTX)); if (!ctx) return NULL; ctx->bn_ctx = BN_CTX_new(); ctx->ca_ctxs = (STACK_OF(CA_CTX *)) sk_new_null(); ctx->cipher_ctx = EVP_CIPHER_CTX_new(); ctx->md_ctx = EVP_MD_CTX_create(); ctx->pace_ctxs = (STACK_OF(PACE_CTX *)) sk_new_null(); ctx->ri_ctxs = (STACK_OF(RI_CTX *)) sk_new_null(); ctx->ssc = BN_new(); ctx->ta_ctx = TA_CTX_new(); if (!ctx->bn_ctx || !ctx->md_ctx || !ctx->pace_ctxs || !ctx->ta_ctx || !ctx->ca_ctxs || !ctx->cipher_ctx || !ctx->ri_ctxs || !ctx->ssc) goto err; BN_CTX_init(ctx->bn_ctx); EVP_CIPHER_CTX_init(ctx->cipher_ctx); ctx->ca_ctx = NULL; ctx->key_ctx = NULL; ctx->pace_ctx = NULL; ctx->ri_ctx = NULL; ctx->tr_version = EAC_TR_VERSION_2_02; return ctx; err: EAC_CTX_clear_free(ctx); return NULL; }
int CRYPTO_get_new_lockid(char *name) { char *str; int i; #if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16) /* A hack to make Visual C++ 5.0 work correctly when linking as * a DLL using /MT. Without this, the application cannot use * and floating point printf's. * It also seems to be needed for Visual C 1.5 (win16) */ SSLeay_MSVC5_hack=(double)name[0]*(double)name[1]; #endif if ((app_locks == NULL) && ((app_locks=sk_new_null()) == NULL)) { CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID,ERR_R_MALLOC_FAILURE); return(0); } if ((str=BUF_strdup(name)) == NULL) { CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID,ERR_R_MALLOC_FAILURE); return(0); } i=sk_push(app_locks,str); if (!i) OPENSSL_free(str); else i+=CRYPTO_NUM_LOCKS; /* gap of one :-) */ return(i); }
int MAIN(int argc, char **argv) { int i,badops=0,offset=0,ret=1,j; unsigned int length=0; long num,tmplen; BIO *in=NULL,*out=NULL,*b64=NULL, *derout = NULL; int informat,indent=0, noout = 0, dump = 0; char *infile=NULL,*str=NULL,*prog,*oidfile=NULL, *derfile=NULL; unsigned char *tmpbuf; BUF_MEM *buf=NULL; STACK *osk=NULL; ASN1_TYPE *at=NULL; informat=FORMAT_PEM; apps_startup(); if (bio_err == NULL) if ((bio_err=BIO_new(BIO_s_file())) != NULL) BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT); prog=argv[0]; argc--; argv++; if ((osk=sk_new_null()) == NULL) { BIO_printf(bio_err,"Memory allocation failure\n"); goto end; } while (argc >= 1) { if (strcmp(*argv,"-inform") == 0) { if (--argc < 1) goto bad; informat=str2fmt(*(++argv)); } else if (strcmp(*argv,"-in") == 0) { if (--argc < 1) goto bad; infile= *(++argv); } else if (strcmp(*argv,"-out") == 0) { if (--argc < 1) goto bad; derfile= *(++argv); } else if (strcmp(*argv,"-i") == 0) { indent=1; } else if (strcmp(*argv,"-noout") == 0) noout = 1; else if (strcmp(*argv,"-oid") == 0) { if (--argc < 1) goto bad; oidfile= *(++argv); } else if (strcmp(*argv,"-offset") == 0) { if (--argc < 1) goto bad; offset= atoi(*(++argv)); } else if (strcmp(*argv,"-length") == 0) { if (--argc < 1) goto bad; length= atoi(*(++argv)); if (length == 0) goto bad; } else if (strcmp(*argv,"-dump") == 0) { dump= -1; } else if (strcmp(*argv,"-dlimit") == 0) { if (--argc < 1) goto bad; dump= atoi(*(++argv)); if (dump <= 0) goto bad; } else if (strcmp(*argv,"-strparse") == 0) { if (--argc < 1) goto bad; sk_push(osk,*(++argv)); } else { BIO_printf(bio_err,"unknown option %s\n",*argv); badops=1; break; } argc--; argv++; } if (badops) { bad: BIO_printf(bio_err,"%s [options] <infile\n",prog); BIO_printf(bio_err,"where options are\n"); BIO_printf(bio_err," -inform arg input format - one of DER TXT PEM\n"); BIO_printf(bio_err," -in arg input file\n"); BIO_printf(bio_err," -out arg output file (output format is always DER\n"); BIO_printf(bio_err," -noout arg don't produce any output\n"); BIO_printf(bio_err," -offset arg offset into file\n"); BIO_printf(bio_err," -length arg length of section in file\n"); BIO_printf(bio_err," -i indent entries\n"); BIO_printf(bio_err," -dump dump unknown data in hex form\n"); BIO_printf(bio_err," -dlimit arg dump the first arg bytes of unknown data in hex form\n"); BIO_printf(bio_err," -oid file file of extra oid definitions\n"); BIO_printf(bio_err," -strparse offset\n"); BIO_printf(bio_err," a series of these can be used to 'dig' into multiple\n"); BIO_printf(bio_err," ASN1 blob wrappings\n"); goto end; } ERR_load_crypto_strings(); in=BIO_new(BIO_s_file()); out=BIO_new(BIO_s_file()); if ((in == NULL) || (out == NULL)) { ERR_print_errors(bio_err); goto end; } BIO_set_fp(out,stdout,BIO_NOCLOSE|BIO_FP_TEXT); #ifdef VMS { BIO *tmpbio = BIO_new(BIO_f_linebuffer()); out = BIO_push(tmpbio, out); } #endif if (oidfile != NULL) { if (BIO_read_filename(in,oidfile) <= 0) { BIO_printf(bio_err,"problems opening %s\n",oidfile); ERR_print_errors(bio_err); goto end; } OBJ_create_objects(in); } if (infile == NULL) BIO_set_fp(in,stdin,BIO_NOCLOSE); else { if (BIO_read_filename(in,infile) <= 0) { perror(infile); goto end; } } if (derfile) { if(!(derout = BIO_new_file(derfile, "wb"))) { BIO_printf(bio_err,"problems opening %s\n",derfile); ERR_print_errors(bio_err); goto end; } } if ((buf=BUF_MEM_new()) == NULL) goto end; if (!BUF_MEM_grow(buf,BUFSIZ*8)) goto end; /* Pre-allocate :-) */ if (informat == FORMAT_PEM) { BIO *tmp; if ((b64=BIO_new(BIO_f_base64())) == NULL) goto end; BIO_push(b64,in); tmp=in; in=b64; b64=tmp; } num=0; for (;;) { if (!BUF_MEM_grow(buf,(int)num+BUFSIZ)) goto end; i=BIO_read(in,&(buf->data[num]),BUFSIZ); if (i <= 0) break; num+=i; } str=buf->data; /* If any structs to parse go through in sequence */ if (sk_num(osk)) { tmpbuf=(unsigned char *)str; tmplen=num; for (i=0; i<sk_num(osk); i++) { ASN1_TYPE *atmp; j=atoi(sk_value(osk,i)); if (j == 0) { BIO_printf(bio_err,"'%s' is an invalid number\n",sk_value(osk,i)); continue; } tmpbuf+=j; tmplen-=j; atmp = at; at = d2i_ASN1_TYPE(NULL,&tmpbuf,tmplen); ASN1_TYPE_free(atmp); if(!at) { BIO_printf(bio_err,"Error parsing structure\n"); ERR_print_errors(bio_err); goto end; } /* hmm... this is a little evil but it works */ tmpbuf=at->value.asn1_string->data; tmplen=at->value.asn1_string->length; } str=(char *)tmpbuf; num=tmplen; } if (length == 0) length=(unsigned int)num; if(derout) { if(BIO_write(derout, str + offset, length) != (int)length) { BIO_printf(bio_err, "Error writing output\n"); ERR_print_errors(bio_err); goto end; } } if (!noout && !ASN1_parse_dump(out,(unsigned char *)&(str[offset]),length, indent,dump)) { ERR_print_errors(bio_err); goto end; } ret=0; end: BIO_free(derout); if (in != NULL) BIO_free(in); if (out != NULL) BIO_free_all(out); if (b64 != NULL) BIO_free(b64); if (ret != 0) ERR_print_errors(bio_err); if (buf != NULL) BUF_MEM_free(buf); if (at != NULL) ASN1_TYPE_free(at); if (osk != NULL) sk_free(osk); OBJ_cleanup(); OPENSSL_EXIT(ret); }
TXT_DB *TXT_DB_read(BIO *in, int num) { TXT_DB *ret = NULL; int er = 1; int esc = 0; long ln = 0; int i, add, n; int size = BUFSIZE; int offset = 0; char *p, **pp, *f; BUF_MEM *buf = NULL; if ((buf = BUF_MEM_new()) == NULL) goto err; if (!BUF_MEM_grow(buf, size)) goto err; if ((ret = (TXT_DB *)OPENSSL_malloc(sizeof(TXT_DB))) == NULL) goto err; ret->num_fields = num; ret->index = NULL; ret->qual = NULL; if ((ret->data = sk_new_null()) == NULL) goto err; if ((ret->index = (LHASH **)OPENSSL_malloc(sizeof(LHASH *) * num)) == NULL) goto err; if ((ret->qual = (int (**)(char **))OPENSSL_malloc(sizeof(int (**)(char **)) * num)) == NULL) goto err; for (i = 0; i < num; i++) { ret->index[i] = NULL; ret->qual[i] = NULL; } add = (num + 1) * sizeof(char *); buf->data[size - 1] = '\0'; offset = 0; for (;;) { if (offset != 0) { size += BUFSIZE; if (!BUF_MEM_grow_clean(buf, size)) goto err; } buf->data[offset] = '\0'; BIO_gets(in, &(buf->data[offset]), size - offset); ln++; if (buf->data[offset] == '\0') break; if ((offset == 0) && (buf->data[0] == '#')) continue; i = strlen(&(buf->data[offset])); offset += i; if (buf->data[offset - 1] != '\n') continue; else { buf->data[offset - 1] = '\0'; /* blat the '\n' */ if (!(p = (char *)OPENSSL_malloc(add + offset))) goto err; offset = 0; } pp = (char **)p; p += add; n = 0; pp[n++] = p; i = 0; f = buf->data; esc = 0; for (;;) { if (*f == '\0') break; if (*f == '\t') { if (esc) p--; else { *(p++) = '\0'; f++; if (n >= num) break; pp[n++] = p; continue; } } esc = (*f == '\\'); *(p++) = *(f++); } *(p++) = '\0'; if ((n != num) || (*f != '\0')) { #if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16) /* temporaty * fix :-( */ fprintf(stderr, "wrong number of fields on line %ld (looking for field %d, got %d, '%s' left)\n", ln, num, n, f); #endif er = 2; goto err; } pp[n] = p; if (!sk_push(ret->data, (char *)pp)) { #if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16) /* temporaty * fix :-( */ fprintf(stderr, "failure in sk_push\n"); #endif er = 2; goto err; }
TokenError _backend_createRequest(const RegutilInfo *info, const char *hostname, const char *password, char **request, size_t *reqlen) { // OpenSSL seeds the PRNG automatically, see the manual page for RAND_add. if (!RAND_status()) { fprintf(stderr, BINNAME ": no random state!\n"); return TokenError_NoRandomState; } // Abort if there are no requests *request = NULL; if (!info->pkcs10) return TokenError_Unknown; // Create certificate requests bool ok = true; CertReq *reqs = NULL; STACK *x509reqs = sk_new_null(); for (const RegutilPKCS10 *pkcs10 = info->pkcs10; pkcs10 != NULL; pkcs10 = pkcs10->next) { RSA *rsa = NULL; EVP_PKEY *privkey = NULL; X509_NAME *subject = NULL; X509_REQ *x509req = NULL; STACK_OF(X509_EXTENSION) *exts = NULL; // Check the parameters. // Maximum key size in OpenSSL: // http://www.mail-archive.com/[email protected]/msg58229.html if (!pkcs10->subjectDN || pkcs10->keySize < 1024 || pkcs10->keySize > 16384) goto req_error; // Generate key pair // FIXME deprecated function // TODO use OPENSSL_NO_DEPRECATED rsa = RSA_generate_key(pkcs10->keySize, RSA_F4, NULL, NULL); if (!rsa) goto req_error; privkey = EVP_PKEY_new(); if (!privkey) goto req_error; EVP_PKEY_assign_RSA(privkey, rsa); // Subject name subject = certutil_parse_dn(pkcs10->subjectDN, pkcs10->includeFullDN); if (!subject) goto req_error; // Create request x509req = X509_REQ_new(); if (!x509req || !X509_REQ_set_version(x509req, 0) || !X509_REQ_set_subject_name(x509req, subject) || !X509_REQ_set_pubkey(x509req, privkey)) { // yes this is correct(!) certutil_updateErrorString(); goto req_error; } // Set attributes exts = sk_X509_EXTENSION_new_null(); if (!exts) goto req_error; X509_EXTENSION *ext = makeKeyUsageExt(pkcs10->keyUsage); if (!ext || !sk_X509_EXTENSION_push(exts, ext)) goto req_error; if (!X509_REQ_add_extensions(x509req, exts)) { certutil_updateErrorString(); goto req_error; } exts = NULL; // Add signature if (!X509_REQ_sign(x509req, privkey, EVP_sha1())) { certutil_updateErrorString(); goto req_error; } // Store in list CertReq *req = malloc(sizeof(CertReq)); req->pkcs10 = pkcs10; req->privkey = privkey; req->rsa = rsa; req->x509 = x509req; req->next = reqs; reqs = req; sk_push(x509reqs, (char*)x509req); continue; req_error: // Clean up and set error flag if (privkey) EVP_PKEY_free(privkey); else if (rsa) RSA_free(rsa); X509_NAME_free(subject); sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); X509_REQ_free(x509req); ok = false; } TokenError error = TokenError_Unknown; if (ok) { // Determine filename from certificate name char *filename = certutil_makeFilename(X509_REQ_get_subject_name(reqs->x509)); // Build the certificate request request_wrap(x509reqs, request, reqlen); if (*request && filename) { // Create the key file in ~/cbt/name.p12 FILE *keyfile = platform_openLocked(filename, Platform_OpenCreate); if (!keyfile) { error = TokenError_CantCreateFile; } else { error = saveKeys(reqs, hostname, password, keyfile); if (!platform_closeLocked(keyfile) && !error) error = TokenError_CantCreateFile; } } if (filename) free(filename); if (error && *request) free(*request); } // Free reqs while (reqs) { RSA_free(reqs->rsa); // This free's privkey too X509_REQ_free(reqs->x509); CertReq *next = reqs->next; free(reqs); reqs = next; } sk_free(x509reqs); return error; }
int MAIN(int argc, char **argv) { ENGINE *e = NULL; char *infile=NULL, *outfile=NULL, *keyname = NULL; char *certfile=NULL; BIO *in=NULL, *out = NULL; char **args; char *name = NULL; char *csp_name = NULL; PKCS12 *p12 = NULL; char pass[50], macpass[50]; int export_cert = 0; int options = 0; int chain = 0; int badarg = 0; int iter = PKCS12_DEFAULT_ITER; int maciter = PKCS12_DEFAULT_ITER; int twopass = 0; int keytype = 0; int cert_pbe = NID_pbe_WithSHA1And40BitRC2_CBC; int key_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; int ret = 1; int macver = 1; int noprompt = 0; STACK *canames = NULL; char *cpass = NULL, *mpass = NULL; char *passargin = NULL, *passargout = NULL, *passarg = NULL; char *passin = NULL, *passout = NULL; char *inrand = NULL; char *CApath = NULL, *CAfile = NULL; char *engine=NULL; apps_startup(); enc = EVP_des_ede3_cbc(); if (bio_err == NULL ) bio_err = BIO_new_fp (stderr, BIO_NOCLOSE); if (!load_config(bio_err, NULL)) goto end; args = argv + 1; while (*args) { if (*args[0] == '-') { if (!strcmp (*args, "-nokeys")) options |= NOKEYS; else if (!strcmp (*args, "-keyex")) keytype = KEY_EX; else if (!strcmp (*args, "-keysig")) keytype = KEY_SIG; else if (!strcmp (*args, "-nocerts")) options |= NOCERTS; else if (!strcmp (*args, "-clcerts")) options |= CLCERTS; else if (!strcmp (*args, "-cacerts")) options |= CACERTS; else if (!strcmp (*args, "-noout")) options |= (NOKEYS|NOCERTS); else if (!strcmp (*args, "-info")) options |= INFO; else if (!strcmp (*args, "-chain")) chain = 1; else if (!strcmp (*args, "-twopass")) twopass = 1; else if (!strcmp (*args, "-nomacver")) macver = 0; else if (!strcmp (*args, "-descert")) cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; else if (!strcmp (*args, "-export")) export_cert = 1; else if (!strcmp (*args, "-des")) enc=EVP_des_cbc(); #ifndef OPENSSL_NO_IDEA else if (!strcmp (*args, "-idea")) enc=EVP_idea_cbc(); #endif else if (!strcmp (*args, "-des3")) enc = EVP_des_ede3_cbc(); #ifndef OPENSSL_NO_AES else if (!strcmp(*args,"-aes128")) enc=EVP_aes_128_cbc(); else if (!strcmp(*args,"-aes192")) enc=EVP_aes_192_cbc(); else if (!strcmp(*args,"-aes256")) enc=EVP_aes_256_cbc(); #endif else if (!strcmp (*args, "-noiter")) iter = 1; else if (!strcmp (*args, "-maciter")) maciter = PKCS12_DEFAULT_ITER; else if (!strcmp (*args, "-nomaciter")) maciter = 1; else if (!strcmp (*args, "-nodes")) enc=NULL; else if (!strcmp (*args, "-certpbe")) { if (args[1]) { args++; cert_pbe=OBJ_txt2nid(*args); if(cert_pbe == NID_undef) { BIO_printf(bio_err, "Unknown PBE algorithm %s\n", *args); badarg = 1; } } else badarg = 1; } else if (!strcmp (*args, "-keypbe")) { if (args[1]) { args++; key_pbe=OBJ_txt2nid(*args); if(key_pbe == NID_undef) { BIO_printf(bio_err, "Unknown PBE algorithm %s\n", *args); badarg = 1; } } else badarg = 1; } else if (!strcmp (*args, "-rand")) { if (args[1]) { args++; inrand = *args; } else badarg = 1; } else if (!strcmp (*args, "-inkey")) { if (args[1]) { args++; keyname = *args; } else badarg = 1; } else if (!strcmp (*args, "-certfile")) { if (args[1]) { args++; certfile = *args; } else badarg = 1; } else if (!strcmp (*args, "-name")) { if (args[1]) { args++; name = *args; } else badarg = 1; } else if (!strcmp (*args, "-CSP")) { if (args[1]) { args++; csp_name = *args; } else badarg = 1; } else if (!strcmp (*args, "-caname")) { if (args[1]) { args++; if (!canames) canames = sk_new_null(); sk_push(canames, *args); } else badarg = 1; } else if (!strcmp (*args, "-in")) { if (args[1]) { args++; infile = *args; } else badarg = 1; } else if (!strcmp (*args, "-out")) { if (args[1]) { args++; outfile = *args; } else badarg = 1; } else if (!strcmp(*args,"-passin")) { if (args[1]) { args++; passargin = *args; } else badarg = 1; } else if (!strcmp(*args,"-passout")) { if (args[1]) { args++; passargout = *args; } else badarg = 1; } else if (!strcmp (*args, "-password")) { if (args[1]) { args++; passarg = *args; noprompt = 1; } else badarg = 1; } else if (!strcmp(*args,"-CApath")) { if (args[1]) { args++; CApath = *args; } else badarg = 1; } else if (!strcmp(*args,"-CAfile")) { if (args[1]) { args++; CAfile = *args; } else badarg = 1; } else if (!strcmp(*args,"-engine")) { if (args[1]) { args++; engine = *args; } else badarg = 1; } else badarg = 1; } else badarg = 1; args++; } if (badarg) { BIO_printf (bio_err, "Usage: pkcs12 [options]\n"); BIO_printf (bio_err, "where options are\n"); BIO_printf (bio_err, "-export output PKCS12 file\n"); BIO_printf (bio_err, "-chain add certificate chain\n"); BIO_printf (bio_err, "-inkey file private key if not infile\n"); BIO_printf (bio_err, "-certfile f add all certs in f\n"); BIO_printf (bio_err, "-CApath arg - PEM format directory of CA's\n"); BIO_printf (bio_err, "-CAfile arg - PEM format file of CA's\n"); BIO_printf (bio_err, "-name \"name\" use name as friendly name\n"); BIO_printf (bio_err, "-caname \"nm\" use nm as CA friendly name (can be used more than once).\n"); BIO_printf (bio_err, "-in infile input filename\n"); BIO_printf (bio_err, "-out outfile output filename\n"); BIO_printf (bio_err, "-noout don't output anything, just verify.\n"); BIO_printf (bio_err, "-nomacver don't verify MAC.\n"); BIO_printf (bio_err, "-nocerts don't output certificates.\n"); BIO_printf (bio_err, "-clcerts only output client certificates.\n"); BIO_printf (bio_err, "-cacerts only output CA certificates.\n"); BIO_printf (bio_err, "-nokeys don't output private keys.\n"); BIO_printf (bio_err, "-info give info about PKCS#12 structure.\n"); BIO_printf (bio_err, "-des encrypt private keys with DES\n"); BIO_printf (bio_err, "-des3 encrypt private keys with triple DES (default)\n"); #ifndef OPENSSL_NO_IDEA BIO_printf (bio_err, "-idea encrypt private keys with idea\n"); #endif #ifndef OPENSSL_NO_AES BIO_printf (bio_err, "-aes128, -aes192, -aes256\n"); BIO_printf (bio_err, " encrypt PEM output with cbc aes\n"); #endif BIO_printf (bio_err, "-nodes don't encrypt private keys\n"); BIO_printf (bio_err, "-noiter don't use encryption iteration\n"); BIO_printf (bio_err, "-maciter use MAC iteration\n"); BIO_printf (bio_err, "-twopass separate MAC, encryption passwords\n"); BIO_printf (bio_err, "-descert encrypt PKCS#12 certificates with triple DES (default RC2-40)\n"); BIO_printf (bio_err, "-certpbe alg specify certificate PBE algorithm (default RC2-40)\n"); BIO_printf (bio_err, "-keypbe alg specify private key PBE algorithm (default 3DES)\n"); BIO_printf (bio_err, "-keyex set MS key exchange type\n"); BIO_printf (bio_err, "-keysig set MS key signature type\n"); BIO_printf (bio_err, "-password p set import/export password source\n"); BIO_printf (bio_err, "-passin p input file pass phrase source\n"); BIO_printf (bio_err, "-passout p output file pass phrase source\n"); BIO_printf (bio_err, "-engine e use engine e, possibly a hardware device.\n"); BIO_printf(bio_err, "-rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR); BIO_printf(bio_err, " load the file (or the files in the directory) into\n"); BIO_printf(bio_err, " the random number generator\n"); goto end; } e = setup_engine(bio_err, engine, 0); if(passarg) { if(export_cert) passargout = passarg; else passargin = passarg; } if(!app_passwd(bio_err, passargin, passargout, &passin, &passout)) { BIO_printf(bio_err, "Error getting passwords\n"); goto end; } if(!cpass) { if(export_cert) cpass = passout; else cpass = passin; } if(cpass) { mpass = cpass; noprompt = 1; } else { cpass = pass; mpass = macpass; } if(export_cert || inrand) { app_RAND_load_file(NULL, bio_err, (inrand != NULL)); if (inrand != NULL) BIO_printf(bio_err,"%ld semi-random bytes loaded\n", app_RAND_load_files(inrand)); } ERR_load_crypto_strings(); #ifdef CRYPTO_MDEBUG CRYPTO_push_info("read files"); #endif if (!infile) in = BIO_new_fp(stdin, BIO_NOCLOSE); else in = BIO_new_file(infile, "rb"); if (!in) { BIO_printf(bio_err, "Error opening input file %s\n", infile ? infile : "<stdin>"); perror (infile); goto end; } #if 0 if (certfile) { if(!(certsin = BIO_new_file(certfile, "r"))) { BIO_printf(bio_err, "Can't open certificate file %s\n", certfile); perror (certfile); goto end; } } if (keyname) { if(!(inkey = BIO_new_file(keyname, "r"))) { BIO_printf(bio_err, "Can't key certificate file %s\n", keyname); perror (keyname); goto end; } } #endif #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); CRYPTO_push_info("write files"); #endif if (!outfile) { out = BIO_new_fp(stdout, BIO_NOCLOSE); #ifdef OPENSSL_SYS_VMS { BIO *tmpbio = BIO_new(BIO_f_linebuffer()); out = BIO_push(tmpbio, out); } #endif } else out = BIO_new_file(outfile, "wb"); if (!out) { BIO_printf(bio_err, "Error opening output file %s\n", outfile ? outfile : "<stdout>"); perror (outfile); goto end; } if (twopass) { #ifdef CRYPTO_MDEBUG CRYPTO_push_info("read MAC password"); #endif if(EVP_read_pw_string (macpass, sizeof macpass, "Enter MAC Password:"******"Can't read Password\n"); goto end; } #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); #endif } if (export_cert) { EVP_PKEY *key = NULL; STACK_OF(PKCS12_SAFEBAG) *bags = NULL; STACK_OF(PKCS7) *safes = NULL; PKCS12_SAFEBAG *bag = NULL; PKCS8_PRIV_KEY_INFO *p8 = NULL; PKCS7 *authsafe = NULL; X509 *ucert = NULL; STACK_OF(X509) *certs=NULL; char *catmp = NULL; int i; unsigned char keyid[EVP_MAX_MD_SIZE]; unsigned int keyidlen = 0; #ifdef CRYPTO_MDEBUG CRYPTO_push_info("process -export_cert"); CRYPTO_push_info("reading private key"); #endif key = load_key(bio_err, keyname ? keyname : infile, FORMAT_PEM, 1, passin, e, "private key"); if (!key) { goto export_end; } #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); CRYPTO_push_info("reading certs from input"); #endif /* Load in all certs in input file */ if(!(certs = load_certs(bio_err, infile, FORMAT_PEM, NULL, e, "certificates"))) { goto export_end; } #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); CRYPTO_push_info("reading certs from input 2"); #endif for(i = 0; i < sk_X509_num(certs); i++) { ucert = sk_X509_value(certs, i); if(X509_check_private_key(ucert, key)) { X509_digest(ucert, EVP_sha1(), keyid, &keyidlen); break; } } if(!keyidlen) { ucert = NULL; BIO_printf(bio_err, "No certificate matches private key\n"); goto export_end; } #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); CRYPTO_push_info("reading certs from certfile"); #endif bags = sk_PKCS12_SAFEBAG_new_null (); /* Add any more certificates asked for */ if (certfile) { STACK_OF(X509) *morecerts=NULL; if(!(morecerts = load_certs(bio_err, certfile, FORMAT_PEM, NULL, e, "certificates from certfile"))) { goto export_end; } while(sk_X509_num(morecerts) > 0) { sk_X509_push(certs, sk_X509_shift(morecerts)); } sk_X509_free(morecerts); } #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); CRYPTO_push_info("building chain"); #endif /* If chaining get chain from user cert */ if (chain) { int vret; STACK_OF(X509) *chain2; X509_STORE *store = X509_STORE_new(); if (!store) { BIO_printf (bio_err, "Memory allocation error\n"); goto export_end; } if (!X509_STORE_load_locations(store, CAfile, CApath)) X509_STORE_set_default_paths (store); vret = get_cert_chain (ucert, store, &chain2); X509_STORE_free(store); if (!vret) { /* Exclude verified certificate */ for (i = 1; i < sk_X509_num (chain2) ; i++) sk_X509_push(certs, sk_X509_value (chain2, i)); /* Free first certificate */ X509_free(sk_X509_value(chain2, 0)); sk_X509_free(chain2); } else { BIO_printf (bio_err, "Error %s getting chain.\n", X509_verify_cert_error_string(vret)); goto export_end; } } #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); CRYPTO_push_info("building bags"); #endif /* We now have loads of certificates: include them all */ for(i = 0; i < sk_X509_num(certs); i++) { X509 *cert = NULL; cert = sk_X509_value(certs, i); bag = PKCS12_x5092certbag(cert); /* If it matches private key set id */ if(cert == ucert) { if(name) PKCS12_add_friendlyname(bag, name, -1); PKCS12_add_localkeyid(bag, keyid, keyidlen); } else if((catmp = sk_shift(canames))) PKCS12_add_friendlyname(bag, catmp, -1); sk_PKCS12_SAFEBAG_push(bags, bag); } sk_X509_pop_free(certs, X509_free); certs = NULL; #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); CRYPTO_push_info("encrypting bags"); #endif if(!noprompt && EVP_read_pw_string(pass, sizeof pass, "Enter Export Password:"******"Can't read Password\n"); goto export_end; } if (!twopass) strcpy(macpass, pass); /* Turn certbags into encrypted authsafe */ authsafe = PKCS12_pack_p7encdata(cert_pbe, cpass, -1, NULL, 0, iter, bags); sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); bags = NULL; if (!authsafe) { ERR_print_errors (bio_err); goto export_end; } safes = sk_PKCS7_new_null (); sk_PKCS7_push (safes, authsafe); #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); CRYPTO_push_info("building shrouded key bag"); #endif /* Make a shrouded key bag */ p8 = EVP_PKEY2PKCS8 (key); if(keytype) PKCS8_add_keyusage(p8, keytype); bag = PKCS12_MAKE_SHKEYBAG(key_pbe, cpass, -1, NULL, 0, iter, p8); PKCS8_PRIV_KEY_INFO_free(p8); p8 = NULL; if (name) PKCS12_add_friendlyname (bag, name, -1); if(csp_name) PKCS12_add_CSPName_asc(bag, csp_name, -1); PKCS12_add_localkeyid (bag, keyid, keyidlen); bags = sk_PKCS12_SAFEBAG_new_null(); sk_PKCS12_SAFEBAG_push (bags, bag); #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); CRYPTO_push_info("encrypting shrouded key bag"); #endif /* Turn it into unencrypted safe bag */ authsafe = PKCS12_pack_p7data (bags); sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); bags = NULL; sk_PKCS7_push (safes, authsafe); #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); CRYPTO_push_info("building pkcs12"); #endif p12 = PKCS12_init(NID_pkcs7_data); PKCS12_pack_authsafes(p12, safes); sk_PKCS7_pop_free(safes, PKCS7_free); safes = NULL; PKCS12_set_mac (p12, mpass, -1, NULL, 0, maciter, NULL); #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); CRYPTO_push_info("writing pkcs12"); #endif i2d_PKCS12_bio (out, p12); ret = 0; export_end: #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); CRYPTO_pop_info(); CRYPTO_push_info("process -export_cert: freeing"); #endif if (key) EVP_PKEY_free(key); if (certs) sk_X509_pop_free(certs, X509_free); if (safes) sk_PKCS7_pop_free(safes, PKCS7_free); if (bags) sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); #endif goto end; } if (!(p12 = d2i_PKCS12_bio (in, NULL))) { ERR_print_errors(bio_err); goto end; } #ifdef CRYPTO_MDEBUG CRYPTO_push_info("read import password"); #endif if(!noprompt && EVP_read_pw_string(pass, sizeof pass, "Enter Import Password:"******"Can't read Password\n"); goto end; } #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); #endif if (!twopass) strcpy(macpass, pass); if (options & INFO) BIO_printf (bio_err, "MAC Iteration %ld\n", p12->mac->iter ? ASN1_INTEGER_get (p12->mac->iter) : 1); if(macver) { #ifdef CRYPTO_MDEBUG CRYPTO_push_info("verify MAC"); #endif /* If we enter empty password try no password first */ if(!macpass[0] && PKCS12_verify_mac(p12, NULL, 0)) { /* If mac and crypto pass the same set it to NULL too */ if(!twopass) cpass = NULL; } else if (!PKCS12_verify_mac(p12, mpass, -1)) { BIO_printf (bio_err, "Mac verify error: invalid password?\n"); ERR_print_errors (bio_err); goto end; } BIO_printf (bio_err, "MAC verified OK\n"); #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); #endif } #ifdef CRYPTO_MDEBUG CRYPTO_push_info("output keys and certificates"); #endif if (!dump_certs_keys_p12 (out, p12, cpass, -1, options, passout)) { BIO_printf(bio_err, "Error outputting keys and certificates\n"); ERR_print_errors (bio_err); goto end; } #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); #endif ret = 0; end: if (p12) PKCS12_free(p12); if(export_cert || inrand) app_RAND_write_file(NULL, bio_err); #ifdef CRYPTO_MDEBUG CRYPTO_remove_all_info(); #endif BIO_free(in); BIO_free_all(out); if (canames) sk_free(canames); if(passin) OPENSSL_free(passin); if(passout) OPENSSL_free(passout); apps_shutdown(); OPENSSL_EXIT(ret); }
STACK *d2i_ASN1_SET(STACK **a, const unsigned char **pp, long length, d2i_of_void *d2i, void (*free_func)(void *), int ex_tag, int ex_class) { ASN1_const_CTX c; STACK *ret=NULL; if ((a == NULL) || ((*a) == NULL)) { if ((ret=sk_new_null()) == NULL) { ASN1err(ASN1_F_D2I_ASN1_SET,ERR_R_MALLOC_FAILURE); goto err; } } else ret=(*a); c.p= *pp; c.max=(length == 0)?0:(c.p+length); c.inf=ASN1_get_object(&c.p,&c.slen,&c.tag,&c.xclass,(long)(c.max-c.p)); if (c.inf & 0x80) goto err; if (ex_class != c.xclass) { ASN1err(ASN1_F_D2I_ASN1_SET,ASN1_R_BAD_CLASS); goto err; } if (ex_tag != c.tag) { ASN1err(ASN1_F_D2I_ASN1_SET,ASN1_R_BAD_TAG); goto err; } if ((c.slen+c.p) > c.max) { ASN1err(ASN1_F_D2I_ASN1_SET,ASN1_R_LENGTH_ERROR); goto err; } /* check for infinite constructed - it can be as long * as the amount of data passed to us */ if (c.inf == (V_ASN1_CONSTRUCTED+1)) c.slen=(long)(length+ *pp-c.p); c.max=c.p+c.slen; while (c.p < c.max) { char *s; if (M_ASN1_D2I_end_sequence()) break; /* XXX: This was called with 4 arguments, incorrectly, it seems if ((s=func(NULL,&c.p,c.slen,c.max-c.p)) == NULL) */ if ((s=d2i(NULL,&c.p,c.slen)) == NULL) { ASN1err(ASN1_F_D2I_ASN1_SET,ASN1_R_ERROR_PARSING_SET_ELEMENT); asn1_add_error(*pp,(int)(c.q- *pp)); goto err; } if (!sk_push(ret,s)) goto err; } if (a != NULL) (*a)=ret; *pp=c.p; return(ret); err: if ((ret != NULL) && ((a == NULL) || (*a != ret))) { if (free_func != NULL) sk_pop_free(ret,free_func); else sk_free(ret); } return(NULL); }
int MAIN(int argc, char **argv) { int ret=1,i; const char **pp; int verbose=0, list_cap=0, test_avail=0, test_avail_noise = 0; ENGINE *e; STACK *engines = sk_new_null(); STACK *pre_cmds = sk_new_null(); STACK *post_cmds = sk_new_null(); int badops=1; BIO *bio_out=NULL; const char *indent = " "; apps_startup(); SSL_load_error_strings(); if (bio_err == NULL) bio_err=BIO_new_fp(stderr,BIO_NOCLOSE); if (!load_config(bio_err, NULL)) goto end; bio_out=BIO_new_fp(stdout,BIO_NOCLOSE); #ifdef OPENSSL_SYS_VMS { BIO *tmpbio = BIO_new(BIO_f_linebuffer()); bio_out = BIO_push(tmpbio, bio_out); } #endif argc--; argv++; while (argc >= 1) { if (strncmp(*argv,"-v",2) == 0) { if(strspn(*argv + 1, "v") < strlen(*argv + 1)) goto skip_arg_loop; if((verbose=strlen(*argv + 1)) > 4) goto skip_arg_loop; } else if (strcmp(*argv,"-c") == 0) list_cap=1; else if (strncmp(*argv,"-t",2) == 0) { test_avail=1; if(strspn(*argv + 1, "t") < strlen(*argv + 1)) goto skip_arg_loop; if((test_avail_noise = strlen(*argv + 1) - 1) > 1) goto skip_arg_loop; } else if (strcmp(*argv,"-pre") == 0) { argc--; argv++; if (argc == 0) goto skip_arg_loop; sk_push(pre_cmds,*argv); } else if (strcmp(*argv,"-post") == 0) { argc--; argv++; if (argc == 0) goto skip_arg_loop; sk_push(post_cmds,*argv); } else if ((strncmp(*argv,"-h",2) == 0) || (strcmp(*argv,"-?") == 0)) goto skip_arg_loop; else sk_push(engines,*argv); argc--; argv++; } /* Looks like everything went OK */ badops = 0; skip_arg_loop: if (badops) { for (pp=engine_usage; (*pp != NULL); pp++) BIO_printf(bio_err,"%s",*pp); goto end; } if (sk_num(engines) == 0) { for(e = ENGINE_get_first(); e != NULL; e = ENGINE_get_next(e)) { sk_push(engines,(char *)ENGINE_get_id(e)); } } for (i=0; i<sk_num(engines); i++) { const char *id = sk_value(engines,i); if ((e = ENGINE_by_id(id)) != NULL) { const char *name = ENGINE_get_name(e); /* Do "id" first, then "name". Easier to auto-parse. */ BIO_printf(bio_out, "(%s) %s\n", id, name); util_do_cmds(e, pre_cmds, bio_out, indent); if (strcmp(ENGINE_get_id(e), id) != 0) { BIO_printf(bio_out, "Loaded: (%s) %s\n", ENGINE_get_id(e), ENGINE_get_name(e)); } if (list_cap) { int cap_size = 256; char *cap_buf = NULL; int k,n; const int *nids; ENGINE_CIPHERS_PTR fn_c; ENGINE_DIGESTS_PTR fn_d; if (ENGINE_get_RSA(e) != NULL && !append_buf(&cap_buf, "RSA", &cap_size, 256)) goto end; if (ENGINE_get_DSA(e) != NULL && !append_buf(&cap_buf, "DSA", &cap_size, 256)) goto end; if (ENGINE_get_DH(e) != NULL && !append_buf(&cap_buf, "DH", &cap_size, 256)) goto end; if (ENGINE_get_RAND(e) != NULL && !append_buf(&cap_buf, "RAND", &cap_size, 256)) goto end; fn_c = ENGINE_get_ciphers(e); if(!fn_c) goto skip_ciphers; n = fn_c(e, NULL, &nids, 0); for(k=0 ; k < n ; ++k) if(!append_buf(&cap_buf, OBJ_nid2sn(nids[k]), &cap_size, 256)) goto end; skip_ciphers: fn_d = ENGINE_get_digests(e); if(!fn_d) goto skip_digests; n = fn_d(e, NULL, &nids, 0); for(k=0 ; k < n ; ++k) if(!append_buf(&cap_buf, OBJ_nid2sn(nids[k]), &cap_size, 256)) goto end; skip_digests: if (cap_buf && (*cap_buf != '\0')) BIO_printf(bio_out, " [%s]\n", cap_buf); OPENSSL_free(cap_buf); } if(test_avail) { BIO_printf(bio_out, "%s", indent); if (ENGINE_init(e)) { BIO_printf(bio_out, "[ available ]\n"); util_do_cmds(e, post_cmds, bio_out, indent); ENGINE_finish(e); } else { BIO_printf(bio_out, "[ unavailable ]\n"); if(test_avail_noise) ERR_print_errors_fp(stdout); ERR_clear_error(); } } if((verbose > 0) && !util_verbose(e, verbose, bio_out, indent)) goto end; ENGINE_free(e); } else ERR_print_errors(bio_err); } ret=0; end: ERR_print_errors(bio_err); sk_pop_free(engines, identity); sk_pop_free(pre_cmds, identity); sk_pop_free(post_cmds, identity); if (bio_out != NULL) BIO_free_all(bio_out); apps_shutdown(); OPENSSL_EXIT(ret); }
static int util_verbose(ENGINE *e, int verbose, BIO *bio_out, const char *indent) { static const int line_wrap = 78; int num; int ret = 0; char *name = NULL; char *desc = NULL; int flags; int xpos = 0; STACK *cmds = NULL; if(!ENGINE_ctrl(e, ENGINE_CTRL_HAS_CTRL_FUNCTION, 0, NULL, NULL) || ((num = ENGINE_ctrl(e, ENGINE_CTRL_GET_FIRST_CMD_TYPE, 0, NULL, NULL)) <= 0)) { #if 0 BIO_printf(bio_out, "%s<no control commands>\n", indent); #endif return 1; } cmds = sk_new_null(); if(!cmds) goto err; do { int len; /* Get the command input flags */ if((flags = ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FLAGS, num, NULL, NULL)) < 0) goto err; if (!(flags & ENGINE_CMD_FLAG_INTERNAL) || verbose >= 4) { /* Get the command name */ if((len = ENGINE_ctrl(e, ENGINE_CTRL_GET_NAME_LEN_FROM_CMD, num, NULL, NULL)) <= 0) goto err; if((name = OPENSSL_malloc(len + 1)) == NULL) goto err; if(ENGINE_ctrl(e, ENGINE_CTRL_GET_NAME_FROM_CMD, num, name, NULL) <= 0) goto err; /* Get the command description */ if((len = ENGINE_ctrl(e, ENGINE_CTRL_GET_DESC_LEN_FROM_CMD, num, NULL, NULL)) < 0) goto err; if(len > 0) { if((desc = OPENSSL_malloc(len + 1)) == NULL) goto err; if(ENGINE_ctrl(e, ENGINE_CTRL_GET_DESC_FROM_CMD, num, desc, NULL) <= 0) goto err; } /* Now decide on the output */ if(xpos == 0) /* Do an indent */ xpos = BIO_printf(bio_out, indent); else /* Otherwise prepend a ", " */ xpos += BIO_printf(bio_out, ", "); if(verbose == 1) { /* We're just listing names, comma-delimited */ if((xpos > (int)strlen(indent)) && (xpos + (int)strlen(name) > line_wrap)) { BIO_printf(bio_out, "\n"); xpos = BIO_printf(bio_out, indent); } xpos += BIO_printf(bio_out, "%s", name); } else { /* We're listing names plus descriptions */ BIO_printf(bio_out, "%s: %s\n", name, (desc == NULL) ? "<no description>" : desc); /* ... and sometimes input flags */ if((verbose >= 3) && !util_flags(bio_out, flags, indent)) goto err; xpos = 0; } } OPENSSL_free(name); name = NULL; if(desc) { OPENSSL_free(desc); desc = NULL; } /* Move to the next command */ num = ENGINE_ctrl(e, ENGINE_CTRL_GET_NEXT_CMD_TYPE, num, NULL, NULL); } while(num > 0); if(xpos > 0) BIO_printf(bio_out, "\n"); ret = 1; err: if(cmds) sk_pop_free(cmds, identity); if(name) OPENSSL_free(name); if(desc) OPENSSL_free(desc); return ret; }
int MAIN(int argc, char **argv) { ENGINE *e = NULL; char **args; char *host = NULL, *port = NULL, *path = "/"; char *reqin = NULL, *respin = NULL; char *reqout = NULL, *respout = NULL; char *signfile = NULL, *keyfile = NULL; char *rsignfile = NULL, *rkeyfile = NULL; char *outfile = NULL; int add_nonce = 1, noverify = 0, use_ssl = -1; OCSP_REQUEST *req = NULL; OCSP_RESPONSE *resp = NULL; OCSP_BASICRESP *bs = NULL; X509 *issuer = NULL, *cert = NULL; X509 *signer = NULL, *rsigner = NULL; EVP_PKEY *key = NULL, *rkey = NULL; BIO *acbio = NULL, *cbio = NULL; BIO *derbio = NULL; BIO *out = NULL; int req_text = 0, resp_text = 0; long nsec = MAX_VALIDITY_PERIOD, maxage = -1; char *CAfile = NULL, *CApath = NULL; X509_STORE *store = NULL; SSL_CTX *ctx = NULL; STACK_OF(X509) *sign_other = NULL, *verify_other = NULL, *rother = NULL; char *sign_certfile = NULL, *verify_certfile = NULL, *rcertfile = NULL; unsigned long sign_flags = 0, verify_flags = 0, rflags = 0; int ret = 1; int accept_count = -1; int badarg = 0; int i; int ignore_err = 0; STACK *reqnames = NULL; STACK_OF(OCSP_CERTID) *ids = NULL; X509 *rca_cert = NULL; char *ridx_filename = NULL; char *rca_filename = NULL; CA_DB *rdb = NULL; int nmin = 0, ndays = -1; if (bio_err == NULL) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); if (!load_config(bio_err, NULL)) goto end; SSL_load_error_strings(); OpenSSL_add_ssl_algorithms(); args = argv + 1; reqnames = sk_new_null(); ids = sk_OCSP_CERTID_new_null(); while (!badarg && *args && *args[0] == '-') { if (!strcmp(*args, "-out")) { if (args[1]) { args++; outfile = *args; } else badarg = 1; } else if (!strcmp(*args, "-url")) { if (args[1]) { args++; if (!OCSP_parse_url(*args, &host, &port, &path, &use_ssl)) { BIO_printf(bio_err, "Error parsing URL\n"); badarg = 1; } } else badarg = 1; } else if (!strcmp(*args, "-host")) { if (args[1]) { args++; host = *args; } else badarg = 1; } else if (!strcmp(*args, "-port")) { if (args[1]) { args++; port = *args; } else badarg = 1; } else if (!strcmp(*args, "-ignore_err")) ignore_err = 1; else if (!strcmp(*args, "-noverify")) noverify = 1; else if (!strcmp(*args, "-nonce")) add_nonce = 2; else if (!strcmp(*args, "-no_nonce")) add_nonce = 0; else if (!strcmp(*args, "-resp_no_certs")) rflags |= OCSP_NOCERTS; else if (!strcmp(*args, "-resp_key_id")) rflags |= OCSP_RESPID_KEY; else if (!strcmp(*args, "-no_certs")) sign_flags |= OCSP_NOCERTS; else if (!strcmp(*args, "-no_signature_verify")) verify_flags |= OCSP_NOSIGS; else if (!strcmp(*args, "-no_cert_verify")) verify_flags |= OCSP_NOVERIFY; else if (!strcmp(*args, "-no_chain")) verify_flags |= OCSP_NOCHAIN; else if (!strcmp(*args, "-no_cert_checks")) verify_flags |= OCSP_NOCHECKS; else if (!strcmp(*args, "-no_explicit")) verify_flags |= OCSP_NOEXPLICIT; else if (!strcmp(*args, "-trust_other")) verify_flags |= OCSP_TRUSTOTHER; else if (!strcmp(*args, "-no_intern")) verify_flags |= OCSP_NOINTERN; else if (!strcmp(*args, "-text")) { req_text = 1; resp_text = 1; } else if (!strcmp(*args, "-req_text")) req_text = 1; else if (!strcmp(*args, "-resp_text")) resp_text = 1; else if (!strcmp(*args, "-reqin")) { if (args[1]) { args++; reqin = *args; } else badarg = 1; } else if (!strcmp(*args, "-respin")) { if (args[1]) { args++; respin = *args; } else badarg = 1; } else if (!strcmp(*args, "-signer")) { if (args[1]) { args++; signfile = *args; } else badarg = 1; } else if (!strcmp (*args, "-VAfile")) { if (args[1]) { args++; verify_certfile = *args; verify_flags |= OCSP_TRUSTOTHER; } else badarg = 1; } else if (!strcmp(*args, "-sign_other")) { if (args[1]) { args++; sign_certfile = *args; } else badarg = 1; } else if (!strcmp(*args, "-verify_other")) { if (args[1]) { args++; verify_certfile = *args; } else badarg = 1; } else if (!strcmp (*args, "-CAfile")) { if (args[1]) { args++; CAfile = *args; } else badarg = 1; } else if (!strcmp (*args, "-CApath")) { if (args[1]) { args++; CApath = *args; } else badarg = 1; } else if (!strcmp (*args, "-validity_period")) { if (args[1]) { args++; nsec = atol(*args); if (nsec < 0) { BIO_printf(bio_err, "Illegal validity period %s\n", *args); badarg = 1; } } else badarg = 1; } else if (!strcmp (*args, "-status_age")) { if (args[1]) { args++; maxage = atol(*args); if (maxage < 0) { BIO_printf(bio_err, "Illegal validity age %s\n", *args); badarg = 1; } } else badarg = 1; } else if (!strcmp(*args, "-signkey")) { if (args[1]) { args++; keyfile = *args; } else badarg = 1; } else if (!strcmp(*args, "-reqout")) { if (args[1]) { args++; reqout = *args; } else badarg = 1; } else if (!strcmp(*args, "-respout")) { if (args[1]) { args++; respout = *args; } else badarg = 1; } else if (!strcmp(*args, "-path")) { if (args[1]) { args++; path = *args; } else badarg = 1; } else if (!strcmp(*args, "-issuer")) { if (args[1]) { args++; X509_free(issuer); issuer = load_cert(bio_err, *args, FORMAT_PEM, NULL, e, "issuer certificate"); if(!issuer) goto end; } else badarg = 1; } else if (!strcmp (*args, "-cert")) { if (args[1]) { args++; X509_free(cert); cert = load_cert(bio_err, *args, FORMAT_PEM, NULL, e, "certificate"); if(!cert) goto end; if(!add_ocsp_cert(&req, cert, issuer, ids)) goto end; if(!sk_push(reqnames, *args)) goto end; } else badarg = 1; } else if (!strcmp(*args, "-serial")) { if (args[1]) { args++; if(!add_ocsp_serial(&req, *args, issuer, ids)) goto end; if(!sk_push(reqnames, *args)) goto end; } else badarg = 1; } else if (!strcmp(*args, "-index")) { if (args[1]) { args++; ridx_filename = *args; } else badarg = 1; } else if (!strcmp(*args, "-CA")) { if (args[1]) { args++; rca_filename = *args; } else badarg = 1; } else if (!strcmp (*args, "-nmin")) { if (args[1]) { args++; nmin = atol(*args); if (nmin < 0) { BIO_printf(bio_err, "Illegal update period %s\n", *args); badarg = 1; } } if (ndays == -1) ndays = 0; else badarg = 1; } else if (!strcmp (*args, "-nrequest")) { if (args[1]) { args++; accept_count = atol(*args); if (accept_count < 0) { BIO_printf(bio_err, "Illegal accept count %s\n", *args); badarg = 1; } } else badarg = 1; } else if (!strcmp (*args, "-ndays")) { if (args[1]) { args++; ndays = atol(*args); if (ndays < 0) { BIO_printf(bio_err, "Illegal update period %s\n", *args); badarg = 1; } } else badarg = 1; } else if (!strcmp(*args, "-rsigner")) { if (args[1]) { args++; rsignfile = *args; } else badarg = 1; } else if (!strcmp(*args, "-rkey")) { if (args[1]) { args++; rkeyfile = *args; } else badarg = 1; } else if (!strcmp(*args, "-rother")) { if (args[1]) { args++; rcertfile = *args; } else badarg = 1; } else badarg = 1; args++; } /* Have we anything to do? */ if (!req && !reqin && !respin && !(port && ridx_filename)) badarg = 1; if (badarg) { BIO_printf (bio_err, "OCSP utility\n"); BIO_printf (bio_err, "Usage ocsp [options]\n"); BIO_printf (bio_err, "where options are\n"); BIO_printf (bio_err, "-out file output filename\n"); BIO_printf (bio_err, "-issuer file issuer certificate\n"); BIO_printf (bio_err, "-cert file certificate to check\n"); BIO_printf (bio_err, "-serial n serial number to check\n"); BIO_printf (bio_err, "-signer file certificate to sign OCSP request with\n"); BIO_printf (bio_err, "-signkey file private key to sign OCSP request with\n"); BIO_printf (bio_err, "-sign_other file additional certificates to include in signed request\n"); BIO_printf (bio_err, "-no_certs don't include any certificates in signed request\n"); BIO_printf (bio_err, "-req_text print text form of request\n"); BIO_printf (bio_err, "-resp_text print text form of response\n"); BIO_printf (bio_err, "-text print text form of request and response\n"); BIO_printf (bio_err, "-reqout file write DER encoded OCSP request to \"file\"\n"); BIO_printf (bio_err, "-respout file write DER encoded OCSP reponse to \"file\"\n"); BIO_printf (bio_err, "-reqin file read DER encoded OCSP request from \"file\"\n"); BIO_printf (bio_err, "-respin file read DER encoded OCSP reponse from \"file\"\n"); BIO_printf (bio_err, "-nonce add OCSP nonce to request\n"); BIO_printf (bio_err, "-no_nonce don't add OCSP nonce to request\n"); BIO_printf (bio_err, "-url URL OCSP responder URL\n"); BIO_printf (bio_err, "-host host:n send OCSP request to host on port n\n"); BIO_printf (bio_err, "-path path to use in OCSP request\n"); BIO_printf (bio_err, "-CApath dir trusted certificates directory\n"); BIO_printf (bio_err, "-CAfile file trusted certificates file\n"); BIO_printf (bio_err, "-VAfile file validator certificates file\n"); BIO_printf (bio_err, "-validity_period n maximum validity discrepancy in seconds\n"); BIO_printf (bio_err, "-status_age n maximum status age in seconds\n"); BIO_printf (bio_err, "-noverify don't verify response at all\n"); BIO_printf (bio_err, "-verify_other file additional certificates to search for signer\n"); BIO_printf (bio_err, "-trust_other don't verify additional certificates\n"); BIO_printf (bio_err, "-no_intern don't search certificates contained in response for signer\n"); BIO_printf (bio_err, "-no_signature_verify don't check signature on response\n"); BIO_printf (bio_err, "-no_cert_verify don't check signing certificate\n"); BIO_printf (bio_err, "-no_chain don't chain verify response\n"); BIO_printf (bio_err, "-no_cert_checks don't do additional checks on signing certificate\n"); BIO_printf (bio_err, "-port num port to run responder on\n"); BIO_printf (bio_err, "-index file certificate status index file\n"); BIO_printf (bio_err, "-CA file CA certificate\n"); BIO_printf (bio_err, "-rsigner file responder certificate to sign responses with\n"); BIO_printf (bio_err, "-rkey file responder key to sign responses with\n"); BIO_printf (bio_err, "-rother file other certificates to include in response\n"); BIO_printf (bio_err, "-resp_no_certs don't include any certificates in response\n"); BIO_printf (bio_err, "-nmin n number of minutes before next update\n"); BIO_printf (bio_err, "-ndays n number of days before next update\n"); BIO_printf (bio_err, "-resp_key_id identify reponse by signing certificate key ID\n"); BIO_printf (bio_err, "-nrequest n number of requests to accept (default unlimited)\n"); goto end; } if(outfile) out = BIO_new_file(outfile, "w"); else out = BIO_new_fp(stdout, BIO_NOCLOSE); if(!out) { BIO_printf(bio_err, "Error opening output file\n"); goto end; } if (!req && (add_nonce != 2)) add_nonce = 0; if (!req && reqin) { derbio = BIO_new_file(reqin, "rb"); if (!derbio) { BIO_printf(bio_err, "Error Opening OCSP request file\n"); goto end; } req = d2i_OCSP_REQUEST_bio(derbio, NULL); BIO_free(derbio); if(!req) { BIO_printf(bio_err, "Error reading OCSP request\n"); goto end; } } if (!req && port) { acbio = init_responder(port); if (!acbio) goto end; } if (rsignfile && !rdb) { if (!rkeyfile) rkeyfile = rsignfile; rsigner = load_cert(bio_err, rsignfile, FORMAT_PEM, NULL, e, "responder certificate"); if (!rsigner) { BIO_printf(bio_err, "Error loading responder certificate\n"); goto end; } rca_cert = load_cert(bio_err, rca_filename, FORMAT_PEM, NULL, e, "CA certificate"); if (rcertfile) { rother = load_certs(bio_err, rcertfile, FORMAT_PEM, NULL, e, "responder other certificates"); if (!rother) goto end; } rkey = load_key(bio_err, rkeyfile, FORMAT_PEM, 0, NULL, NULL, "responder private key"); if (!rkey) goto end; } if(acbio) BIO_printf(bio_err, "Waiting for OCSP client connections...\n"); redo_accept: if (acbio) { if (!do_responder(&req, &cbio, acbio, port)) goto end; if (!req) { resp = OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, NULL); send_ocsp_response(cbio, resp); goto done_resp; } } if (!req && (signfile || reqout || host || add_nonce || ridx_filename)) { BIO_printf(bio_err, "Need an OCSP request for this operation!\n"); goto end; } if (req && add_nonce) OCSP_request_add1_nonce(req, NULL, -1); if (signfile) { if (!keyfile) keyfile = signfile; signer = load_cert(bio_err, signfile, FORMAT_PEM, NULL, e, "signer certificate"); if (!signer) { BIO_printf(bio_err, "Error loading signer certificate\n"); goto end; } if (sign_certfile) { sign_other = load_certs(bio_err, sign_certfile, FORMAT_PEM, NULL, e, "signer certificates"); if (!sign_other) goto end; } key = load_key(bio_err, keyfile, FORMAT_PEM, 0, NULL, NULL, "signer private key"); if (!key) goto end; if (!OCSP_request_sign(req, signer, key, EVP_sha1(), sign_other, sign_flags)) { BIO_printf(bio_err, "Error signing OCSP request\n"); goto end; } } if (req_text && req) OCSP_REQUEST_print(out, req, 0); if (reqout) { derbio = BIO_new_file(reqout, "wb"); if(!derbio) { BIO_printf(bio_err, "Error opening file %s\n", reqout); goto end; } i2d_OCSP_REQUEST_bio(derbio, req); BIO_free(derbio); } if (ridx_filename && (!rkey || !rsigner || !rca_cert)) { BIO_printf(bio_err, "Need a responder certificate, key and CA for this operation!\n"); goto end; } if (ridx_filename && !rdb) { rdb = load_index(ridx_filename, NULL); if (!rdb) goto end; if (!index_index(rdb)) goto end; } if (rdb) { i = make_ocsp_response(&resp, req, rdb, rca_cert, rsigner, rkey, rother, rflags, nmin, ndays); if (cbio) send_ocsp_response(cbio, resp); } else if (host) { #ifndef OPENSSL_NO_SOCK cbio = BIO_new_connect(host); #else BIO_printf(bio_err, "Error creating connect BIO - sockets not supported.\n"); goto end; #endif if (!cbio) { BIO_printf(bio_err, "Error creating connect BIO\n"); goto end; } if (port) BIO_set_conn_port(cbio, port); if (use_ssl == 1) { BIO *sbio; #if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3) ctx = SSL_CTX_new(SSLv23_client_method()); #elif !defined(OPENSSL_NO_SSL3) ctx = SSL_CTX_new(SSLv3_client_method()); #elif !defined(OPENSSL_NO_SSL2) ctx = SSL_CTX_new(SSLv2_client_method()); #else BIO_printf(bio_err, "SSL is disabled\n"); goto end; #endif if (ctx == NULL) { BIO_printf(bio_err, "Error creating SSL context.\n"); goto end; } SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY); sbio = BIO_new_ssl(ctx, 1); cbio = BIO_push(sbio, cbio); } if (BIO_do_connect(cbio) <= 0) { BIO_printf(bio_err, "Error connecting BIO\n"); goto end; } resp = OCSP_sendreq_bio(cbio, path, req); BIO_free_all(cbio); cbio = NULL; if (!resp) { BIO_printf(bio_err, "Error querying OCSP responsder\n"); goto end; } } else if (respin) { derbio = BIO_new_file(respin, "rb"); if (!derbio) { BIO_printf(bio_err, "Error Opening OCSP response file\n"); goto end; } resp = d2i_OCSP_RESPONSE_bio(derbio, NULL); BIO_free(derbio); if(!resp) { BIO_printf(bio_err, "Error reading OCSP response\n"); goto end; } } else { ret = 0; goto end; } done_resp: if (respout) { derbio = BIO_new_file(respout, "wb"); if(!derbio) { BIO_printf(bio_err, "Error opening file %s\n", respout); goto end; } i2d_OCSP_RESPONSE_bio(derbio, resp); BIO_free(derbio); } i = OCSP_response_status(resp); if (i != OCSP_RESPONSE_STATUS_SUCCESSFUL) { BIO_printf(out, "Responder Error: %s (%d)\n", OCSP_response_status_str(i), i); if (ignore_err) goto redo_accept; ret = 0; goto end; } if (resp_text) OCSP_RESPONSE_print(out, resp, 0); /* If running as responder don't verify our own response */ if (cbio) { if (accept_count > 0) accept_count--; /* Redo if more connections needed */ if (accept_count) { BIO_free_all(cbio); cbio = NULL; OCSP_REQUEST_free(req); req = NULL; OCSP_RESPONSE_free(resp); resp = NULL; goto redo_accept; } goto end; } if (!store) store = setup_verify(bio_err, CAfile, CApath); if (!store) goto end; if (verify_certfile) { verify_other = load_certs(bio_err, verify_certfile, FORMAT_PEM, NULL, e, "validator certificate"); if (!verify_other) goto end; } bs = OCSP_response_get1_basic(resp); if (!bs) { BIO_printf(bio_err, "Error parsing response\n"); goto end; } if (!noverify) { if (req && ((i = OCSP_check_nonce(req, bs)) <= 0)) { if (i == -1) BIO_printf(bio_err, "WARNING: no nonce in response\n"); else { BIO_printf(bio_err, "Nonce Verify error\n"); goto end; } } i = OCSP_basic_verify(bs, verify_other, store, verify_flags); if (i < 0) i = OCSP_basic_verify(bs, NULL, store, 0); if(i <= 0) { BIO_printf(bio_err, "Response Verify Failure\n"); ERR_print_errors(bio_err); } else BIO_printf(bio_err, "Response verify OK\n"); } if (!print_ocsp_summary(out, bs, req, reqnames, ids, nsec, maxage)) goto end; ret = 0; end: ERR_print_errors(bio_err); X509_free(signer); X509_STORE_free(store); EVP_PKEY_free(key); EVP_PKEY_free(rkey); X509_free(issuer); X509_free(cert); X509_free(rsigner); X509_free(rca_cert); free_index(rdb); BIO_free_all(cbio); BIO_free_all(acbio); BIO_free(out); OCSP_REQUEST_free(req); OCSP_RESPONSE_free(resp); OCSP_BASICRESP_free(bs); sk_free(reqnames); sk_OCSP_CERTID_free(ids); sk_X509_pop_free(sign_other, X509_free); sk_X509_pop_free(verify_other, X509_free); if (use_ssl != -1) { OPENSSL_free(host); OPENSSL_free(port); OPENSSL_free(path); SSL_CTX_free(ctx); } OPENSSL_EXIT(ret); }
static int asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in, long len, const ASN1_TEMPLATE *tt, char opt, ASN1_TLC *ctx) { int flags, aclass; int ret; const unsigned char *p, *q; if (!val) return 0; flags = tt->flags; aclass = flags & ASN1_TFLG_TAG_CLASS; p = *in; q = p; if (flags & ASN1_TFLG_SK_MASK) { /* SET OF, SEQUENCE OF */ int sktag, skaclass; char sk_eoc; /* First work out expected inner tag value */ if (flags & ASN1_TFLG_IMPTAG) { sktag = tt->tag; skaclass = aclass; } else { skaclass = V_ASN1_UNIVERSAL; if (flags & ASN1_TFLG_SET_OF) sktag = V_ASN1_SET; else sktag = V_ASN1_SEQUENCE; } /* Get the tag */ ret = asn1_check_tlen(&len, NULL, NULL, &sk_eoc, NULL, &p, len, sktag, skaclass, opt, ctx); if (!ret) { ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_NESTED_ASN1_ERROR); return 0; } else if (ret == -1) return -1; if (!*val) *val = (ASN1_VALUE *)sk_new_null(); else { /* We've got a valid STACK: free up any items present */ STACK *sktmp = (STACK *)*val; ASN1_VALUE *vtmp; while(sk_num(sktmp) > 0) { vtmp = (ASN1_VALUE *)sk_pop(sktmp); ASN1_item_ex_free(&vtmp, ASN1_ITEM_ptr(tt->item)); } } if (!*val) { ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_MALLOC_FAILURE); goto err; } /* Read as many items as we can */ while(len > 0) { ASN1_VALUE *skfield; q = p; /* See if EOC found */ if (asn1_check_eoc(&p, len)) { if (!sk_eoc) { ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ASN1_R_UNEXPECTED_EOC); goto err; } len -= p - q; sk_eoc = 0; break; } skfield = NULL; if (!ASN1_item_ex_d2i(&skfield, &p, len, ASN1_ITEM_ptr(tt->item), -1, 0, 0, ctx)) { ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_NESTED_ASN1_ERROR); goto err; } len -= p - q; if (!sk_push((STACK *)*val, (char *)skfield)) { ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_MALLOC_FAILURE); goto err; } } if (sk_eoc) { ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ASN1_R_MISSING_EOC); goto err; } } else if (flags & ASN1_TFLG_IMPTAG) { /* IMPLICIT tagging */ ret = ASN1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item), tt->tag, aclass, opt, ctx); if (!ret) { ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_NESTED_ASN1_ERROR); goto err; } else if (ret == -1) return -1; } else { /* Nothing special */ ret = ASN1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item), -1, 0, opt, ctx); if (!ret) { ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_NESTED_ASN1_ERROR); goto err; } else if (ret == -1) return -1; } *in = p; return 1; err: ASN1_template_free(val, tt); return 0; }
/* * der points to the start of one or more DER-encoded keys. If there is * more than one key, the keys must be contained in multi-key CGA * extensions. * * Returns a stack of EVP_PKEYs on success. */ _STACK * cga_der2keys(uint8_t *der, int dlen) { uint8_t *dk; EVP_PKEY *k; int klen, elen; uint16_t type; _STACK *sk; if ((sk = sk_new_null()) == NULL) { APPLOG_NOMEM(); return (NULL); } /* Extract first key, not in an extension */ dk = cga_parse_key(der, &klen); DBG(&dbg_asn1, "getting key 1 (klen %d dlen %d)", klen, dlen); if ((k = cga_der2key(der, klen)) == NULL) { goto fail; } if (sk_push(sk, (void *)k) == 0) { APPLOG_NOMEM(); goto fail; } /* Extract any keys in extensions */ der += klen; dlen -= klen; while (dlen > 0) { if (cga_parse_next_ext(der, dlen, &elen, &type) < 0) { goto fail; } DBG(&dbg_asn1, "got extension type %d len %d", type, elen); if (dlen < elen) { DBG(&dbg_asn1, "elen > dlen (%d / %d)", elen, dlen); goto fail; } if (type != CGA_MULTIKEY_EXT) { goto next; } dk = cga_get_multikey_key(der, &klen); DBG(&dbg_asn1, "getting ext key (%d bytes)", klen); if ((k = cga_der2key(dk, klen)) == NULL) { goto fail; } if (sk_insert(sk, (void *)k, 0) == 0) { APPLOG_NOMEM(); goto fail; } next: dlen -= elen; der += elen; } return (sk); fail: cga_free_keystack(sk); return (NULL); }
int MAIN(int argc, char **argv) { int i,badops=0; BIO *in=NULL,*out=NULL; int informat,outformat; char *infile,*outfile,*prog,*certfile; PKCS7 *p7 = NULL; PKCS7_SIGNED *p7s = NULL; X509_CRL *crl=NULL; STACK *certflst=NULL; STACK_OF(X509_CRL) *crl_stack=NULL; STACK_OF(X509) *cert_stack=NULL; int ret=1,nocrl=0; apps_startup(); if (bio_err == NULL) if ((bio_err=BIO_new(BIO_s_file())) != NULL) BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT); infile=NULL; outfile=NULL; informat=FORMAT_PEM; outformat=FORMAT_PEM; prog=argv[0]; argc--; argv++; while (argc >= 1) { if (strcmp(*argv,"-inform") == 0) { if (--argc < 1) goto bad; informat=str2fmt(*(++argv)); } else if (strcmp(*argv,"-outform") == 0) { if (--argc < 1) goto bad; outformat=str2fmt(*(++argv)); } else if (strcmp(*argv,"-in") == 0) { if (--argc < 1) goto bad; infile= *(++argv); } else if (strcmp(*argv,"-nocrl") == 0) { nocrl=1; } else if (strcmp(*argv,"-out") == 0) { if (--argc < 1) goto bad; outfile= *(++argv); } else if (strcmp(*argv,"-certfile") == 0) { if (--argc < 1) goto bad; if(!certflst) certflst = sk_new_null(); sk_push(certflst,*(++argv)); } else { BIO_printf(bio_err,"unknown option %s\n",*argv); badops=1; break; } argc--; argv++; } if (badops) { bad: BIO_printf(bio_err,"%s [options] <infile >outfile\n",prog); BIO_printf(bio_err,"where options are\n"); BIO_printf(bio_err," -inform arg input format - DER or PEM\n"); BIO_printf(bio_err," -outform arg output format - DER or PEM\n"); BIO_printf(bio_err," -in arg input file\n"); BIO_printf(bio_err," -out arg output file\n"); BIO_printf(bio_err," -certfile arg certificates file of chain to a trusted CA\n"); BIO_printf(bio_err," (can be used more than once)\n"); BIO_printf(bio_err," -nocrl no crl to load, just certs from '-certfile'\n"); EXIT(1); } ERR_load_crypto_strings(); in=BIO_new(BIO_s_file()); out=BIO_new(BIO_s_file()); if ((in == NULL) || (out == NULL)) { ERR_print_errors(bio_err); goto end; } if (!nocrl) { if (infile == NULL) BIO_set_fp(in,stdin,BIO_NOCLOSE); else { if (BIO_read_filename(in,infile) <= 0) { perror(infile); goto end; } } if (informat == FORMAT_ASN1) crl=d2i_X509_CRL_bio(in,NULL); else if (informat == FORMAT_PEM) crl=PEM_read_bio_X509_CRL(in,NULL,NULL,NULL); else { BIO_printf(bio_err,"bad input format specified for input crl\n"); goto end; } if (crl == NULL) { BIO_printf(bio_err,"unable to load CRL\n"); ERR_print_errors(bio_err); goto end; } } if ((p7=PKCS7_new()) == NULL) goto end; if ((p7s=PKCS7_SIGNED_new()) == NULL) goto end; p7->type=OBJ_nid2obj(NID_pkcs7_signed); p7->d.sign=p7s; p7s->contents->type=OBJ_nid2obj(NID_pkcs7_data); if (!ASN1_INTEGER_set(p7s->version,1)) goto end; if ((crl_stack=sk_X509_CRL_new_null()) == NULL) goto end; p7s->crl=crl_stack; if (crl != NULL) { sk_X509_CRL_push(crl_stack,crl); crl=NULL; /* now part of p7 for OPENSSL_freeing */ } if ((cert_stack=sk_X509_new_null()) == NULL) goto end; p7s->cert=cert_stack; if(certflst) for(i = 0; i < sk_num(certflst); i++) { certfile = sk_value(certflst, i); if (add_certs_from_file(cert_stack,certfile) < 0) { BIO_printf(bio_err, "error loading certificates\n"); ERR_print_errors(bio_err); goto end; } } sk_free(certflst); if (outfile == NULL) { BIO_set_fp(out,stdout,BIO_NOCLOSE); #ifdef VMS { BIO *tmpbio = BIO_new(BIO_f_linebuffer()); out = BIO_push(tmpbio, out); } #endif } else { if (BIO_write_filename(out,outfile) <= 0) { perror(outfile); goto end; } } if (outformat == FORMAT_ASN1) i=i2d_PKCS7_bio(out,p7); else if (outformat == FORMAT_PEM) i=PEM_write_bio_PKCS7(out,p7); else { BIO_printf(bio_err,"bad output format specified for outfile\n"); goto end; } if (!i) { BIO_printf(bio_err,"unable to write pkcs7 object\n"); ERR_print_errors(bio_err); goto end; } ret=0; end: if (in != NULL) BIO_free(in); if (out != NULL) BIO_free_all(out); if (p7 != NULL) PKCS7_free(p7); if (crl != NULL) X509_CRL_free(crl); EXIT(ret); }