static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *value) { STACK_OF(POLICYINFO) *pols = NULL; char *pstr; POLICYINFO *pol; ASN1_OBJECT *pobj; STACK_OF(CONF_VALUE) *vals; CONF_VALUE *cnf; int i, ia5org; pols = sk_POLICYINFO_new_null(); if (pols == NULL) { X509V3err(X509V3_F_R2I_CERTPOL, ERR_R_MALLOC_FAILURE); return NULL; } vals = X509V3_parse_list(value); if (vals == NULL) { X509V3err(X509V3_F_R2I_CERTPOL, ERR_R_X509V3_LIB); goto err; } ia5org = 0; for(i = 0; i < sk_CONF_VALUE_num(vals); i++) { cnf = sk_CONF_VALUE_value(vals, i); if(cnf->value || !cnf->name ) { X509V3err(X509V3_F_R2I_CERTPOL,X509V3_R_INVALID_POLICY_IDENTIFIER); X509V3_conf_err(cnf); goto err; } pstr = cnf->name; if(!strcmp(pstr,"ia5org")) { ia5org = 1; continue; } else if(*pstr == '@') { STACK_OF(CONF_VALUE) *polsect; polsect = X509V3_get_section(ctx, pstr + 1); if(!polsect) { X509V3err(X509V3_F_R2I_CERTPOL,X509V3_R_INVALID_SECTION); X509V3_conf_err(cnf); goto err; } pol = policy_section(ctx, polsect, ia5org); X509V3_section_free(ctx, polsect); if(!pol) goto err; } else { if(!(pobj = OBJ_txt2obj(cnf->name, 0))) { X509V3err(X509V3_F_R2I_CERTPOL,X509V3_R_INVALID_OBJECT_IDENTIFIER); X509V3_conf_err(cnf); goto err; } pol = POLICYINFO_new(); pol->policyid = pobj; } sk_POLICYINFO_push(pols, pol); } sk_CONF_VALUE_pop_free(vals, X509V3_conf_free); return pols; err: sk_CONF_VALUE_pop_free(vals, X509V3_conf_free); sk_POLICYINFO_pop_free(pols, POLICYINFO_free); return NULL; }
int ndn_verify_signature(const unsigned char *msg, size_t size, const struct ndn_parsed_ContentObject *co, const struct ndn_pkey *verification_pubkey) { EVP_MD_CTX verc; EVP_MD_CTX *ver_ctx = &verc; X509_SIG *digest_info = NULL; const unsigned char *dd = NULL; MP_info *merkle_path_info = NULL; unsigned char *root_hash = NULL; size_t root_hash_size; int res; const EVP_MD *digest = NULL; const EVP_MD *merkle_path_digest = NULL; const unsigned char *signature_bits = NULL; size_t signature_bits_size = 0; const unsigned char *witness = NULL; size_t witness_size = 0; const unsigned char *digest_algorithm = NULL; size_t digest_algorithm_size; EVP_PKEY *pkey = (EVP_PKEY *)verification_pubkey; res = ndn_ref_tagged_BLOB(NDN_DTAG_SignatureBits, msg, co->offset[NDN_PCO_B_SignatureBits], co->offset[NDN_PCO_E_SignatureBits], &signature_bits, &signature_bits_size); if (res < 0) return (-1); if (co->offset[NDN_PCO_B_DigestAlgorithm] == co->offset[NDN_PCO_E_DigestAlgorithm]) { digest_algorithm = (const unsigned char *)NDN_SIGNING_DEFAULT_DIGEST_ALGORITHM; } else { /* figure out what algorithm the OID represents */ res = ndn_ref_tagged_string(NDN_DTAG_DigestAlgorithm, msg, co->offset[NDN_PCO_B_DigestAlgorithm], co->offset[NDN_PCO_E_DigestAlgorithm], &digest_algorithm, &digest_algorithm_size); if (res < 0) return (-1); /* NOTE: since the element closer is a 0, and the element is well formed, * the string will be null terminated */ } digest = md_from_digest_and_pkey((const char *)digest_algorithm, verification_pubkey); EVP_MD_CTX_init(ver_ctx); res = EVP_VerifyInit_ex(ver_ctx, digest, NULL); if (!res) { EVP_MD_CTX_cleanup(ver_ctx); return (-1); } if (co->offset[NDN_PCO_B_Witness] != co->offset[NDN_PCO_E_Witness]) { /* The witness is a DigestInfo, where the octet-string therein encapsulates * a sequence of [integer (origin 1 node#), sequence of [octet-string]] * where the inner octet-string is the concatenated hashes on the merkle-path */ res = ndn_ref_tagged_BLOB(NDN_DTAG_Witness, msg, co->offset[NDN_PCO_B_Witness], co->offset[NDN_PCO_E_Witness], &witness, &witness_size); if (res < 0) { EVP_MD_CTX_cleanup(ver_ctx); return (-1); } digest_info = d2i_X509_SIG(NULL, &witness, witness_size); /* digest_info->algor->algorithm->{length, data} * digest_info->digest->{length, type, data} */ /* ...2.2 is an MHT w/ SHA256 */ ASN1_OBJECT *merkle_hash_tree_oid = OBJ_txt2obj("1.2.840.113550.11.1.2.2", 1); if (0 != OBJ_cmp(digest_info->algor->algorithm, merkle_hash_tree_oid)) { fprintf(stderr, "A witness is present without an MHT OID!\n"); EVP_MD_CTX_cleanup(ver_ctx); ASN1_OBJECT_free(merkle_hash_tree_oid); return (-1); } /* we're doing an MHT */ ASN1_OBJECT_free(merkle_hash_tree_oid); merkle_path_digest = EVP_sha256(); /* DER-encoded in the digest_info's digest ASN.1 octet string is the Merkle path info */ dd = digest_info->digest->data; merkle_path_info = d2i_MP_info(NULL, &dd, digest_info->digest->length); X509_SIG_free(digest_info); #ifdef DEBUG int x,h; int node = ASN1_INTEGER_get(merkle_path_info->node); int hash_count = sk_ASN1_OCTET_STRING_num(merkle_path_info->hashes); ASN1_OCTET_STRING *hash; fprintf(stderr, "A witness is present with an MHT OID\n"); fprintf(stderr, "This is node %d, with %d hashes\n", node, hash_count); for (h = 0; h < hash_count; h++) { hash = sk_ASN1_OCTET_STRING_value(merkle_path_info->hashes, h); fprintf(stderr, " hashes[%d] len = %d data = ", h, hash->length); for (x = 0; x < hash->length; x++) { fprintf(stderr, "%02x", hash->data[x]); } fprintf(stderr, "\n"); } #endif /* In the MHT signature case, we signed/verify the root hash */ root_hash_size = EVP_MD_size(merkle_path_digest); root_hash = calloc(1, root_hash_size); res = ndn_merkle_root_hash(msg, size, co, merkle_path_digest, merkle_path_info, root_hash, root_hash_size); MP_info_free(merkle_path_info); if (res < 0) { EVP_MD_CTX_cleanup(ver_ctx); free(root_hash); return(-1); } res = EVP_VerifyUpdate(ver_ctx, root_hash, root_hash_size); free(root_hash); if (res == 0) { EVP_MD_CTX_cleanup(ver_ctx); return(-1); } res = EVP_VerifyFinal(ver_ctx, signature_bits, signature_bits_size, pkey); EVP_MD_CTX_cleanup(ver_ctx); } else { /* * In the simple signature case, we signed/verify from the name through * the end of the content. */ size_t signed_size = co->offset[NDN_PCO_E_Content] - co->offset[NDN_PCO_B_Name]; res = EVP_VerifyUpdate(ver_ctx, msg + co->offset[NDN_PCO_B_Name], signed_size); if (res == 0) { EVP_MD_CTX_cleanup(ver_ctx); return(-1); } res = EVP_VerifyFinal(ver_ctx, signature_bits, signature_bits_size, pkey); EVP_MD_CTX_cleanup(ver_ctx); } return (res); }
static int process_pci_value(CONF_VALUE *val, ASN1_OBJECT **language, ASN1_INTEGER **pathlen, ASN1_OCTET_STRING **policy) { int free_policy = 0; if (strcmp(val->name, "language") == 0) { if (*language) { X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_POLICY_LANGUAGE_ALREADTY_DEFINED); X509V3_conf_err(val); return 0; } if (!(*language = OBJ_txt2obj(val->value, 0))) { X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_INVALID_OBJECT_IDENTIFIER); X509V3_conf_err(val); return 0; } } else if (strcmp(val->name, "pathlen") == 0) { if (*pathlen) { X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_POLICY_PATH_LENGTH_ALREADTY_DEFINED); X509V3_conf_err(val); return 0; } if (!X509V3_get_value_int(val, pathlen)) { X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_POLICY_PATH_LENGTH); X509V3_conf_err(val); return 0; } } else if (strcmp(val->name, "policy") == 0) { unsigned char *tmp_data = NULL; long val_len; if (!*policy) { *policy = ASN1_OCTET_STRING_new(); if (!*policy) { X509V3err(X509V3_F_PROCESS_PCI_VALUE,ERR_R_MALLOC_FAILURE); X509V3_conf_err(val); return 0; } free_policy = 1; } if (strncmp(val->value, "hex:", 4) == 0) { unsigned char *tmp_data2 = string_to_hex(val->value + 4, &val_len); if (!tmp_data2) goto err; tmp_data = OPENSSL_realloc((*policy)->data, (*policy)->length + val_len + 1); if (tmp_data) { (*policy)->data = tmp_data; memcpy(&(*policy)->data[(*policy)->length], tmp_data2, val_len); (*policy)->length += val_len; (*policy)->data[(*policy)->length] = '\0'; } } else if (strncmp(val->value, "file:", 5) == 0) { #ifndef SYMBIAN unsigned char buf[2048]; #else unsigned char buf[1024]; #endif int n; BIO *b = BIO_new_file(val->value + 5, "r"); if (!b) { X509V3err(X509V3_F_PROCESS_PCI_VALUE,ERR_R_BIO_LIB); X509V3_conf_err(val); goto err; } while((n = BIO_read(b, buf, sizeof(buf))) > 0 || (n == 0 && BIO_should_retry(b))) { if (!n) continue; tmp_data = OPENSSL_realloc((*policy)->data, (*policy)->length + n + 1); if (!tmp_data) break; (*policy)->data = tmp_data; memcpy(&(*policy)->data[(*policy)->length], buf, n); (*policy)->length += n; (*policy)->data[(*policy)->length] = '\0'; } if (n < 0) { X509V3err(X509V3_F_PROCESS_PCI_VALUE,ERR_R_BIO_LIB); X509V3_conf_err(val); goto err; } } else if (strncmp(val->value, "text:", 5) == 0) { val_len = strlen(val->value + 5); tmp_data = OPENSSL_realloc((*policy)->data, (*policy)->length + val_len + 1); if (tmp_data) { (*policy)->data = tmp_data; memcpy(&(*policy)->data[(*policy)->length], val->value + 5, val_len); (*policy)->length += val_len; (*policy)->data[(*policy)->length] = '\0'; } } else { X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_INCORRECT_POLICY_SYNTAX_TAG); X509V3_conf_err(val); goto err; } if (!tmp_data) { X509V3err(X509V3_F_PROCESS_PCI_VALUE,ERR_R_MALLOC_FAILURE); X509V3_conf_err(val); goto err; } } return 1; err: if (free_policy) { ASN1_OCTET_STRING_free(*policy); *policy = NULL; } return 0; }
int main(int argc, char **argv) { BIO* in=NULL; BIO* out=NULL; char * outfile = NULL; char * infile = NULL ; int tabLength=100; char *binaryptr; char* mimetype; char* mimetypeaccept=NULL; char* contenttype; const char** pp; unsigned char* hostporturl = NULL; BIO * p12bio ; char **args = argv + 1; unsigned char * serverurl; sslctxparm p; char *response; CURLcode res; struct curl_slist * headers=NULL; int badarg=0; binaryptr=(char*)malloc(tabLength); p.verbose = 0; p.errorbio = BIO_new_fp (stderr, BIO_NOCLOSE); curl_global_init(CURL_GLOBAL_DEFAULT); /* we need some more for the P12 decoding */ OpenSSL_add_all_ciphers(); OpenSSL_add_all_digests(); ERR_load_crypto_strings(); while (*args && *args[0] == '-') { if (!strcmp (*args, "-in")) { if (args[1]) { infile=*(++args); } else badarg=1; } else if (!strcmp (*args, "-out")) { if (args[1]) { outfile=*(++args); } else badarg=1; } else if (!strcmp (*args, "-p12")) { if (args[1]) { p.p12file = *(++args); } else badarg=1; } else if (strcmp(*args,"-envpass") == 0) { if (args[1]) { p.pst = getenv(*(++args)); } else badarg=1; } else if (strcmp(*args,"-connect") == 0) { if (args[1]) { hostporturl = *(++args); } else badarg=1; } else if (strcmp(*args,"-mimetype") == 0) { if (args[1]) { mimetype = *(++args); } else badarg=1; } else if (strcmp(*args,"-acceptmime") == 0) { if (args[1]) { mimetypeaccept = *(++args); } else badarg=1; } else if (strcmp(*args,"-accesstype") == 0) { if (args[1]) { if ((p.accesstype = OBJ_obj2nid(OBJ_txt2obj(*++args,0))) == 0) badarg=1; } else badarg=1; } else if (strcmp(*args,"-verbose") == 0) { p.verbose++; } else badarg=1; args++; } if (mimetype==NULL || mimetypeaccept == NULL) badarg = 1; if (badarg) { for (pp=curlx_usage; (*pp != NULL); pp++) BIO_printf(p.errorbio,"%s\n",*pp); BIO_printf(p.errorbio,"\n"); goto err; } /* set input */ if ((in=BIO_new(BIO_s_file())) == NULL) { BIO_printf(p.errorbio, "Error setting input bio\n"); goto err; } else if (infile == NULL) BIO_set_fp(in,stdin,BIO_NOCLOSE|BIO_FP_TEXT); else if (BIO_read_filename(in,infile) <= 0) { BIO_printf(p.errorbio, "Error opening input file %s\n", infile); BIO_free(in); goto err; } /* set output */ if ((out=BIO_new(BIO_s_file())) == NULL) { BIO_printf(p.errorbio, "Error setting output bio.\n"); goto err; } else if (outfile == NULL) BIO_set_fp(out,stdout,BIO_NOCLOSE|BIO_FP_TEXT); else if (BIO_write_filename(out,outfile) <= 0) { BIO_printf(p.errorbio, "Error opening output file %s\n", outfile); BIO_free(out); goto err; } p.errorbio = BIO_new_fp (stderr, BIO_NOCLOSE); if (!(p.curl = curl_easy_init())) { BIO_printf(p.errorbio, "Cannot init curl lib\n"); goto err; } if (!(p12bio = BIO_new_file(p.p12file , "rb"))) { BIO_printf(p.errorbio, "Error opening P12 file %s\n", p.p12file); goto err; } if (!(p.p12 = d2i_PKCS12_bio (p12bio, NULL))) { BIO_printf(p.errorbio, "Cannot decode P12 structure %s\n", p.p12file); goto err; } p.ca= NULL; if (!(PKCS12_parse (p.p12, p.pst, &(p.pkey), &(p.usercert), &(p.ca) ) )) { BIO_printf(p.errorbio,"Invalid P12 structure in %s\n", p.p12file); goto err; } if (sk_X509_num(p.ca) <= 0) { BIO_printf(p.errorbio,"No trustworthy CA given.%s\n", p.p12file); goto err; } if (p.verbose > 1) X509_print_ex(p.errorbio,p.usercert,0,0); /* determine URL to go */ if (hostporturl) { serverurl=(char*) malloc(9+strlen(hostporturl)); sprintf(serverurl,"https://%s",hostporturl); } else if (p.accesstype != 0) { /* see whether we can find an AIA or SIA for a given access type */ if (!(serverurl = my_get_ext(p.usercert,p.accesstype,NID_info_access))) { int j=0; BIO_printf(p.errorbio,"no service URL in user cert " "cherching in others certificats\n"); for (j=0;j<sk_X509_num(p.ca);j++) { if ((serverurl = my_get_ext(sk_X509_value(p.ca,j),p.accesstype, NID_info_access))) break; if ((serverurl = my_get_ext(sk_X509_value(p.ca,j),p.accesstype, NID_sinfo_access))) break; } } } if (!serverurl) { BIO_printf(p.errorbio, "no service URL in certificats," " check '-accesstype (AD_DVCS | ad_timestamping)'" " or use '-connect'\n"); goto err; } if (p.verbose) BIO_printf(p.errorbio, "Service URL: <%s>\n", serverurl); curl_easy_setopt(p.curl, CURLOPT_URL, serverurl); /* Now specify the POST binary data */ curl_easy_setopt(p.curl, CURLOPT_POSTFIELDS, binaryptr); curl_easy_setopt(p.curl, CURLOPT_POSTFIELDSIZE,tabLength); /* pass our list of custom made headers */ contenttype=(char*) malloc(15+strlen(mimetype)); sprintf(contenttype,"Content-type: %s",mimetype); headers = curl_slist_append(headers,contenttype); curl_easy_setopt(p.curl, CURLOPT_HTTPHEADER, headers); if (p.verbose) BIO_printf(p.errorbio, "Service URL: <%s>\n", serverurl); { FILE *outfp; BIO_get_fp(out,&outfp); curl_easy_setopt(p.curl, CURLOPT_FILE,outfp); } res = curl_easy_setopt(p.curl, CURLOPT_SSL_CTX_FUNCTION, sslctxfun) ; if (res != CURLE_OK) BIO_printf(p.errorbio,"%d %s=%d %d\n", __LINE__, "CURLOPT_SSL_CTX_FUNCTION",CURLOPT_SSL_CTX_FUNCTION,res); curl_easy_setopt(p.curl, CURLOPT_SSL_CTX_DATA, &p); { int lu; int i=0; while ((lu = BIO_read (in,&binaryptr[i],tabLength-i)) >0 ) { i+=lu; if (i== tabLength) { tabLength+=100; binaryptr=(char*)realloc(binaryptr,tabLength); /* should be more careful */ } } tabLength = i; } /* Now specify the POST binary data */ curl_easy_setopt(p.curl, CURLOPT_POSTFIELDS, binaryptr); curl_easy_setopt(p.curl, CURLOPT_POSTFIELDSIZE,tabLength); /* Perform the request, res will get the return code */ BIO_printf(p.errorbio,"%d %s %d\n", __LINE__, "curl_easy_perform", res = curl_easy_perform(p.curl)); { int result =curl_easy_getinfo(p.curl,CURLINFO_CONTENT_TYPE,&response); if( mimetypeaccept && p.verbose) if(!strcmp(mimetypeaccept,response)) BIO_printf(p.errorbio,"the response has a correct mimetype : %s\n", response); else BIO_printf(p.errorbio,"the reponse doesn\'t has an acceptable " "mime type, it is %s instead of %s\n", response,mimetypeaccept); } /*** code d'erreur si accept mime ***, egalement code return HTTP != 200 ***/ /* free the header list*/ curl_slist_free_all(headers); /* always cleanup */ curl_easy_cleanup(p.curl); BIO_free(in); BIO_free(out); return (EXIT_SUCCESS); err: BIO_printf(p.errorbio,"error"); exit(1); }
int cms_main(int argc, char **argv) { ASN1_OBJECT *econtent_type = NULL; BIO *in = NULL, *out = NULL, *indata = NULL, *rctin = NULL; CMS_ContentInfo *cms = NULL, *rcms = NULL; CMS_ReceiptRequest *rr = NULL; ENGINE *e = NULL; EVP_PKEY *key = NULL; const EVP_CIPHER *cipher = NULL, *wrap_cipher = NULL; const EVP_MD *sign_md = NULL; STACK_OF(OPENSSL_STRING) *rr_to = NULL, *rr_from = NULL; STACK_OF(OPENSSL_STRING) *sksigners = NULL, *skkeys = NULL; STACK_OF(X509) *encerts = NULL, *other = NULL; X509 *cert = NULL, *recip = NULL, *signer = NULL; X509_STORE *store = NULL; X509_VERIFY_PARAM *vpm = NULL; char *certfile = NULL, *keyfile = NULL, *contfile = NULL; const char *CAfile = NULL, *CApath = NULL; char *certsoutfile = NULL; int noCAfile = 0, noCApath = 0; char *infile = NULL, *outfile = NULL, *rctfile = NULL, *inrand = NULL; char *passinarg = NULL, *passin = NULL, *signerfile = NULL, *recipfile = NULL; char *to = NULL, *from = NULL, *subject = NULL, *prog; cms_key_param *key_first = NULL, *key_param = NULL; int flags = CMS_DETACHED, noout = 0, print = 0, keyidx = -1, vpmtouched = 0; int informat = FORMAT_SMIME, outformat = FORMAT_SMIME; int need_rand = 0, operation = 0, ret = 1, rr_print = 0, rr_allorfirst = -1; int verify_retcode = 0, rctformat = FORMAT_SMIME, keyform = FORMAT_PEM; size_t secret_keylen = 0, secret_keyidlen = 0; unsigned char *pwri_pass = NULL, *pwri_tmp = NULL; unsigned char *secret_key = NULL, *secret_keyid = NULL; long ltmp; const char *mime_eol = "\n"; OPTION_CHOICE o; if ((vpm = X509_VERIFY_PARAM_new()) == NULL) return 1; prog = opt_init(argc, argv, cms_options); while ((o = opt_next()) != OPT_EOF) { switch (o) { case OPT_EOF: case OPT_ERR: opthelp: BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); goto end; case OPT_HELP: opt_help(cms_options); ret = 0; goto end; case OPT_INFORM: if (!opt_format(opt_arg(), OPT_FMT_PDS, &informat)) goto opthelp; break; case OPT_OUTFORM: if (!opt_format(opt_arg(), OPT_FMT_PDS, &outformat)) goto opthelp; break; case OPT_OUT: outfile = opt_arg(); break; case OPT_ENCRYPT: operation = SMIME_ENCRYPT; break; case OPT_DECRYPT: operation = SMIME_DECRYPT; break; case OPT_SIGN: operation = SMIME_SIGN; break; case OPT_SIGN_RECEIPT: operation = SMIME_SIGN_RECEIPT; break; case OPT_RESIGN: operation = SMIME_RESIGN; break; case OPT_VERIFY: operation = SMIME_VERIFY; break; case OPT_VERIFY_RETCODE: verify_retcode = 1; break; case OPT_VERIFY_RECEIPT: operation = SMIME_VERIFY_RECEIPT; rctfile = opt_arg(); break; case OPT_CMSOUT: operation = SMIME_CMSOUT; break; case OPT_DATA_OUT: operation = SMIME_DATAOUT; break; case OPT_DATA_CREATE: operation = SMIME_DATA_CREATE; break; case OPT_DIGEST_VERIFY: operation = SMIME_DIGEST_VERIFY; break; case OPT_DIGEST_CREATE: operation = SMIME_DIGEST_CREATE; break; case OPT_COMPRESS: operation = SMIME_COMPRESS; break; case OPT_UNCOMPRESS: operation = SMIME_UNCOMPRESS; break; case OPT_ED_DECRYPT: operation = SMIME_ENCRYPTED_DECRYPT; break; case OPT_ED_ENCRYPT: operation = SMIME_ENCRYPTED_ENCRYPT; break; case OPT_DEBUG_DECRYPT: flags |= CMS_DEBUG_DECRYPT; break; case OPT_TEXT: flags |= CMS_TEXT; break; case OPT_ASCIICRLF: flags |= CMS_ASCIICRLF; break; case OPT_NOINTERN: flags |= CMS_NOINTERN; break; case OPT_NOVERIFY: flags |= CMS_NO_SIGNER_CERT_VERIFY; break; case OPT_NOCERTS: flags |= CMS_NOCERTS; break; case OPT_NOATTR: flags |= CMS_NOATTR; break; case OPT_NODETACH: flags &= ~CMS_DETACHED; break; case OPT_NOSMIMECAP: flags |= CMS_NOSMIMECAP; break; case OPT_BINARY: flags |= CMS_BINARY; break; case OPT_KEYID: flags |= CMS_USE_KEYID; break; case OPT_NOSIGS: flags |= CMS_NOSIGS; break; case OPT_NO_CONTENT_VERIFY: flags |= CMS_NO_CONTENT_VERIFY; break; case OPT_NO_ATTR_VERIFY: flags |= CMS_NO_ATTR_VERIFY; break; case OPT_INDEF: flags |= CMS_STREAM; break; case OPT_NOINDEF: flags &= ~CMS_STREAM; break; case OPT_CRLFEOL: mime_eol = "\r\n"; flags |= CMS_CRLFEOL; break; case OPT_NOOUT: noout = 1; break; case OPT_RR_PRINT: rr_print = 1; break; case OPT_RR_ALL: rr_allorfirst = 0; break; case OPT_RR_FIRST: rr_allorfirst = 1; break; case OPT_RCTFORM: if (rctformat == FORMAT_SMIME) rcms = SMIME_read_CMS(rctin, NULL); else if (rctformat == FORMAT_PEM) rcms = PEM_read_bio_CMS(rctin, NULL, NULL, NULL); else if (rctformat == FORMAT_ASN1) if (!opt_format(opt_arg(), OPT_FMT_PEMDER | OPT_FMT_SMIME, &rctformat)) goto opthelp; break; case OPT_CERTFILE: certfile = opt_arg(); break; case OPT_CAFILE: CAfile = opt_arg(); break; case OPT_CAPATH: CApath = opt_arg(); break; case OPT_NOCAFILE: noCAfile = 1; break; case OPT_NOCAPATH: noCApath = 1; break; case OPT_IN: infile = opt_arg(); break; case OPT_CONTENT: contfile = opt_arg(); break; case OPT_RR_FROM: if (rr_from == NULL && (rr_from = sk_OPENSSL_STRING_new_null()) == NULL) goto end; sk_OPENSSL_STRING_push(rr_from, opt_arg()); break; case OPT_RR_TO: if (rr_to == NULL && (rr_to = sk_OPENSSL_STRING_new_null()) == NULL) goto end; sk_OPENSSL_STRING_push(rr_to, opt_arg()); break; case OPT_PRINT: noout = print = 1; break; case OPT_SECRETKEY: if (secret_key != NULL) { BIO_printf(bio_err, "Invalid key (supplied twice) %s\n", opt_arg()); goto opthelp; } secret_key = OPENSSL_hexstr2buf(opt_arg(), <mp); if (secret_key == NULL) { BIO_printf(bio_err, "Invalid key %s\n", opt_arg()); goto end; } secret_keylen = (size_t)ltmp; break; case OPT_SECRETKEYID: if (secret_keyid != NULL) { BIO_printf(bio_err, "Invalid id (supplied twice) %s\n", opt_arg()); goto opthelp; } secret_keyid = OPENSSL_hexstr2buf(opt_arg(), <mp); if (secret_keyid == NULL) { BIO_printf(bio_err, "Invalid id %s\n", opt_arg()); goto opthelp; } secret_keyidlen = (size_t)ltmp; break; case OPT_PWRI_PASSWORD: pwri_pass = (unsigned char *)opt_arg(); break; case OPT_ECONTENT_TYPE: if (econtent_type != NULL) { BIO_printf(bio_err, "Invalid OID (supplied twice) %s\n", opt_arg()); goto opthelp; } econtent_type = OBJ_txt2obj(opt_arg(), 0); if (econtent_type == NULL) { BIO_printf(bio_err, "Invalid OID %s\n", opt_arg()); goto opthelp; } break; case OPT_RAND: inrand = opt_arg(); need_rand = 1; break; case OPT_ENGINE: e = setup_engine(opt_arg(), 0); break; case OPT_PASSIN: passinarg = opt_arg(); break; case OPT_TO: to = opt_arg(); break; case OPT_FROM: from = opt_arg(); break; case OPT_SUBJECT: subject = opt_arg(); break; case OPT_CERTSOUT: certsoutfile = opt_arg(); break; case OPT_MD: if (!opt_md(opt_arg(), &sign_md)) goto end; break; case OPT_SIGNER: /* If previous -signer argument add signer to list */ if (signerfile) { if (sksigners == NULL && (sksigners = sk_OPENSSL_STRING_new_null()) == NULL) goto end; sk_OPENSSL_STRING_push(sksigners, signerfile); if (keyfile == NULL) keyfile = signerfile; if (skkeys == NULL && (skkeys = sk_OPENSSL_STRING_new_null()) == NULL) goto end; sk_OPENSSL_STRING_push(skkeys, keyfile); keyfile = NULL; } signerfile = opt_arg(); break; case OPT_INKEY: /* If previous -inkey argument add signer to list */ if (keyfile) { if (signerfile == NULL) { BIO_puts(bio_err, "Illegal -inkey without -signer\n"); goto end; } if (sksigners == NULL && (sksigners = sk_OPENSSL_STRING_new_null()) == NULL) goto end; sk_OPENSSL_STRING_push(sksigners, signerfile); signerfile = NULL; if (skkeys == NULL && (skkeys = sk_OPENSSL_STRING_new_null()) == NULL) goto end; sk_OPENSSL_STRING_push(skkeys, keyfile); } keyfile = opt_arg(); break; case OPT_KEYFORM: if (!opt_format(opt_arg(), OPT_FMT_ANY, &keyform)) goto opthelp; break; case OPT_RECIP: if (operation == SMIME_ENCRYPT) { if (encerts == NULL && (encerts = sk_X509_new_null()) == NULL) goto end; cert = load_cert(opt_arg(), FORMAT_PEM, "recipient certificate file"); if (cert == NULL) goto end; sk_X509_push(encerts, cert); cert = NULL; } else recipfile = opt_arg(); break; case OPT_CIPHER: if (!opt_cipher(opt_unknown(), &cipher)) goto end; break; case OPT_KEYOPT: keyidx = -1; if (operation == SMIME_ENCRYPT) { if (encerts) keyidx += sk_X509_num(encerts); } else { if (keyfile || signerfile) keyidx++; if (skkeys) keyidx += sk_OPENSSL_STRING_num(skkeys); } if (keyidx < 0) { BIO_printf(bio_err, "No key specified\n"); goto opthelp; } if (key_param == NULL || key_param->idx != keyidx) { cms_key_param *nparam; nparam = app_malloc(sizeof(*nparam), "key param buffer"); nparam->idx = keyidx; if ((nparam->param = sk_OPENSSL_STRING_new_null()) == NULL) goto end; nparam->next = NULL; if (key_first == NULL) key_first = nparam; else key_param->next = nparam; key_param = nparam; } sk_OPENSSL_STRING_push(key_param->param, opt_arg()); break; case OPT_V_CASES: if (!opt_verify(o, vpm)) goto end; vpmtouched++; break; case OPT_3DES_WRAP: # ifndef OPENSSL_NO_DES wrap_cipher = EVP_des_ede3_wrap(); # endif break; case OPT_AES128_WRAP: wrap_cipher = EVP_aes_128_wrap(); break; case OPT_AES192_WRAP: wrap_cipher = EVP_aes_192_wrap(); break; case OPT_AES256_WRAP: wrap_cipher = EVP_aes_256_wrap(); break; } } argc = opt_num_rest(); argv = opt_rest(); if (((rr_allorfirst != -1) || rr_from) && !rr_to) { BIO_puts(bio_err, "No Signed Receipts Recipients\n"); goto opthelp; } if (!(operation & SMIME_SIGNERS) && (rr_to || rr_from)) { BIO_puts(bio_err, "Signed receipts only allowed with -sign\n"); goto opthelp; } if (!(operation & SMIME_SIGNERS) && (skkeys || sksigners)) { BIO_puts(bio_err, "Multiple signers or keys not allowed\n"); goto opthelp; } if (operation & SMIME_SIGNERS) { if (keyfile && !signerfile) { BIO_puts(bio_err, "Illegal -inkey without -signer\n"); goto opthelp; } /* Check to see if any final signer needs to be appended */ if (signerfile) { if (!sksigners && (sksigners = sk_OPENSSL_STRING_new_null()) == NULL) goto end; sk_OPENSSL_STRING_push(sksigners, signerfile); if (!skkeys && (skkeys = sk_OPENSSL_STRING_new_null()) == NULL) goto end; if (!keyfile) keyfile = signerfile; sk_OPENSSL_STRING_push(skkeys, keyfile); } if (!sksigners) { BIO_printf(bio_err, "No signer certificate specified\n"); goto opthelp; } signerfile = NULL; keyfile = NULL; need_rand = 1; } else if (operation == SMIME_DECRYPT) { if (!recipfile && !keyfile && !secret_key && !pwri_pass) { BIO_printf(bio_err, "No recipient certificate or key specified\n"); goto opthelp; } } else if (operation == SMIME_ENCRYPT) { if (*argv == NULL && !secret_key && !pwri_pass && !encerts) { BIO_printf(bio_err, "No recipient(s) certificate(s) specified\n"); goto opthelp; } need_rand = 1; } else if (!operation) goto opthelp; if (!app_passwd(passinarg, NULL, &passin, NULL)) { BIO_printf(bio_err, "Error getting password\n"); goto end; } if (need_rand) { app_RAND_load_file(NULL, (inrand != NULL)); if (inrand != NULL) BIO_printf(bio_err, "%ld semi-random bytes loaded\n", app_RAND_load_files(inrand)); } ret = 2; if (!(operation & SMIME_SIGNERS)) flags &= ~CMS_DETACHED; if (!(operation & SMIME_OP)) { if (flags & CMS_BINARY) outformat = FORMAT_BINARY; } if (!(operation & SMIME_IP)) { if (flags & CMS_BINARY) informat = FORMAT_BINARY; } if (operation == SMIME_ENCRYPT) { if (!cipher) { # ifndef OPENSSL_NO_DES cipher = EVP_des_ede3_cbc(); # else BIO_printf(bio_err, "No cipher selected\n"); goto end; # endif } if (secret_key && !secret_keyid) { BIO_printf(bio_err, "No secret key id\n"); goto end; } if (*argv && !encerts) if ((encerts = sk_X509_new_null()) == NULL) goto end; while (*argv) { if ((cert = load_cert(*argv, FORMAT_PEM, "recipient certificate file")) == NULL) goto end; sk_X509_push(encerts, cert); cert = NULL; argv++; } } if (certfile) { if (!load_certs(certfile, &other, FORMAT_PEM, NULL, "certificate file")) { ERR_print_errors(bio_err); goto end; } } if (recipfile && (operation == SMIME_DECRYPT)) { if ((recip = load_cert(recipfile, FORMAT_PEM, "recipient certificate file")) == NULL) { ERR_print_errors(bio_err); goto end; } } if (operation == SMIME_SIGN_RECEIPT) { if ((signer = load_cert(signerfile, FORMAT_PEM, "receipt signer certificate file")) == NULL) { ERR_print_errors(bio_err); goto end; } } if (operation == SMIME_DECRYPT) { if (!keyfile) keyfile = recipfile; } else if ((operation == SMIME_SIGN) || (operation == SMIME_SIGN_RECEIPT)) { if (!keyfile) keyfile = signerfile; } else keyfile = NULL; if (keyfile) { key = load_key(keyfile, keyform, 0, passin, e, "signing key file"); if (!key) goto end; } in = bio_open_default(infile, 'r', informat); if (in == NULL) goto end; if (operation & SMIME_IP) { if (informat == FORMAT_SMIME) cms = SMIME_read_CMS(in, &indata); else if (informat == FORMAT_PEM) cms = PEM_read_bio_CMS(in, NULL, NULL, NULL); else if (informat == FORMAT_ASN1) cms = d2i_CMS_bio(in, NULL); else { BIO_printf(bio_err, "Bad input format for CMS file\n"); goto end; } if (!cms) { BIO_printf(bio_err, "Error reading S/MIME message\n"); goto end; } if (contfile) { BIO_free(indata); if ((indata = BIO_new_file(contfile, "rb")) == NULL) { BIO_printf(bio_err, "Can't read content file %s\n", contfile); goto end; } } if (certsoutfile) { STACK_OF(X509) *allcerts; allcerts = CMS_get1_certs(cms); if (!save_certs(certsoutfile, allcerts)) { BIO_printf(bio_err, "Error writing certs to %s\n", certsoutfile); ret = 5; goto end; } sk_X509_pop_free(allcerts, X509_free); } } if (rctfile) { char *rctmode = (rctformat == FORMAT_ASN1) ? "rb" : "r"; if ((rctin = BIO_new_file(rctfile, rctmode)) == NULL) { BIO_printf(bio_err, "Can't open receipt file %s\n", rctfile); goto end; } if (rctformat == FORMAT_SMIME) rcms = SMIME_read_CMS(rctin, NULL); else if (rctformat == FORMAT_PEM) rcms = PEM_read_bio_CMS(rctin, NULL, NULL, NULL); else if (rctformat == FORMAT_ASN1) rcms = d2i_CMS_bio(rctin, NULL); else { BIO_printf(bio_err, "Bad input format for receipt\n"); goto end; } if (!rcms) { BIO_printf(bio_err, "Error reading receipt\n"); goto end; } } out = bio_open_default(outfile, 'w', outformat); if (out == NULL) goto end; if ((operation == SMIME_VERIFY) || (operation == SMIME_VERIFY_RECEIPT)) { if ((store = setup_verify(CAfile, CApath, noCAfile, noCApath)) == NULL) goto end; X509_STORE_set_verify_cb(store, cms_cb); if (vpmtouched) X509_STORE_set1_param(store, vpm); } ret = 3; if (operation == SMIME_DATA_CREATE) { cms = CMS_data_create(in, flags); } else if (operation == SMIME_DIGEST_CREATE) { cms = CMS_digest_create(in, sign_md, flags); } else if (operation == SMIME_COMPRESS) { cms = CMS_compress(in, -1, flags); } else if (operation == SMIME_ENCRYPT) { int i; flags |= CMS_PARTIAL; cms = CMS_encrypt(NULL, in, cipher, flags); if (!cms) goto end; for (i = 0; i < sk_X509_num(encerts); i++) { CMS_RecipientInfo *ri; cms_key_param *kparam; int tflags = flags; X509 *x = sk_X509_value(encerts, i); for (kparam = key_first; kparam; kparam = kparam->next) { if (kparam->idx == i) { tflags |= CMS_KEY_PARAM; break; } } ri = CMS_add1_recipient_cert(cms, x, tflags); if (!ri) goto end; if (kparam) { EVP_PKEY_CTX *pctx; pctx = CMS_RecipientInfo_get0_pkey_ctx(ri); if (!cms_set_pkey_param(pctx, kparam->param)) goto end; } if (CMS_RecipientInfo_type(ri) == CMS_RECIPINFO_AGREE && wrap_cipher) { EVP_CIPHER_CTX *wctx; wctx = CMS_RecipientInfo_kari_get0_ctx(ri); EVP_EncryptInit_ex(wctx, wrap_cipher, NULL, NULL, NULL); } } if (secret_key) { if (!CMS_add0_recipient_key(cms, NID_undef, secret_key, secret_keylen, secret_keyid, secret_keyidlen, NULL, NULL, NULL)) goto end; /* NULL these because call absorbs them */ secret_key = NULL; secret_keyid = NULL; } if (pwri_pass) { pwri_tmp = (unsigned char *)OPENSSL_strdup((char *)pwri_pass); if (!pwri_tmp) goto end; if (!CMS_add0_recipient_password(cms, -1, NID_undef, NID_undef, pwri_tmp, -1, NULL)) goto end; pwri_tmp = NULL; } if (!(flags & CMS_STREAM)) { if (!CMS_final(cms, in, NULL, flags)) goto end; } } else if (operation == SMIME_ENCRYPTED_ENCRYPT) { cms = CMS_EncryptedData_encrypt(in, cipher, secret_key, secret_keylen, flags); } else if (operation == SMIME_SIGN_RECEIPT) { CMS_ContentInfo *srcms = NULL; STACK_OF(CMS_SignerInfo) *sis; CMS_SignerInfo *si; sis = CMS_get0_SignerInfos(cms); if (!sis) goto end; si = sk_CMS_SignerInfo_value(sis, 0); srcms = CMS_sign_receipt(si, signer, key, other, flags); if (!srcms) goto end; CMS_ContentInfo_free(cms); cms = srcms; } else if (operation & SMIME_SIGNERS) { int i; /* * If detached data content we enable streaming if S/MIME output * format. */ if (operation == SMIME_SIGN) { if (flags & CMS_DETACHED) { if (outformat == FORMAT_SMIME) flags |= CMS_STREAM; } flags |= CMS_PARTIAL; cms = CMS_sign(NULL, NULL, other, in, flags); if (!cms) goto end; if (econtent_type) CMS_set1_eContentType(cms, econtent_type); if (rr_to) { rr = make_receipt_request(rr_to, rr_allorfirst, rr_from); if (!rr) { BIO_puts(bio_err, "Signed Receipt Request Creation Error\n"); goto end; } } } else flags |= CMS_REUSE_DIGEST; for (i = 0; i < sk_OPENSSL_STRING_num(sksigners); i++) { CMS_SignerInfo *si; cms_key_param *kparam; int tflags = flags; signerfile = sk_OPENSSL_STRING_value(sksigners, i); keyfile = sk_OPENSSL_STRING_value(skkeys, i); signer = load_cert(signerfile, FORMAT_PEM, "signer certificate"); if (!signer) { ret = 2; goto end; } key = load_key(keyfile, keyform, 0, passin, e, "signing key file"); if (!key) { ret = 2; goto end; } for (kparam = key_first; kparam; kparam = kparam->next) { if (kparam->idx == i) { tflags |= CMS_KEY_PARAM; break; } } si = CMS_add1_signer(cms, signer, key, sign_md, tflags); if (!si) goto end; if (kparam) { EVP_PKEY_CTX *pctx; pctx = CMS_SignerInfo_get0_pkey_ctx(si); if (!cms_set_pkey_param(pctx, kparam->param)) goto end; } if (rr && !CMS_add1_ReceiptRequest(si, rr)) goto end; X509_free(signer); signer = NULL; EVP_PKEY_free(key); key = NULL; } /* If not streaming or resigning finalize structure */ if ((operation == SMIME_SIGN) && !(flags & CMS_STREAM)) { if (!CMS_final(cms, in, NULL, flags)) goto end; } } if (!cms) { BIO_printf(bio_err, "Error creating CMS structure\n"); goto end; } ret = 4; if (operation == SMIME_DECRYPT) { if (flags & CMS_DEBUG_DECRYPT) CMS_decrypt(cms, NULL, NULL, NULL, NULL, flags); if (secret_key) { if (!CMS_decrypt_set1_key(cms, secret_key, secret_keylen, secret_keyid, secret_keyidlen)) { BIO_puts(bio_err, "Error decrypting CMS using secret key\n"); goto end; } } if (key) { if (!CMS_decrypt_set1_pkey(cms, key, recip)) { BIO_puts(bio_err, "Error decrypting CMS using private key\n"); goto end; } } if (pwri_pass) { if (!CMS_decrypt_set1_password(cms, pwri_pass, -1)) { BIO_puts(bio_err, "Error decrypting CMS using password\n"); goto end; } } if (!CMS_decrypt(cms, NULL, NULL, indata, out, flags)) { BIO_printf(bio_err, "Error decrypting CMS structure\n"); goto end; } } else if (operation == SMIME_DATAOUT) { if (!CMS_data(cms, out, flags)) goto end; } else if (operation == SMIME_UNCOMPRESS) { if (!CMS_uncompress(cms, indata, out, flags)) goto end; } else if (operation == SMIME_DIGEST_VERIFY) { if (CMS_digest_verify(cms, indata, out, flags) > 0) BIO_printf(bio_err, "Verification successful\n"); else { BIO_printf(bio_err, "Verification failure\n"); goto end; } } else if (operation == SMIME_ENCRYPTED_DECRYPT) { if (!CMS_EncryptedData_decrypt(cms, secret_key, secret_keylen, indata, out, flags)) goto end; } else if (operation == SMIME_VERIFY) { if (CMS_verify(cms, other, store, indata, out, flags) > 0) BIO_printf(bio_err, "Verification successful\n"); else { BIO_printf(bio_err, "Verification failure\n"); if (verify_retcode) ret = verify_err + 32; goto end; } if (signerfile) { STACK_OF(X509) *signers; signers = CMS_get0_signers(cms); if (!save_certs(signerfile, signers)) { BIO_printf(bio_err, "Error writing signers to %s\n", signerfile); ret = 5; goto end; } sk_X509_free(signers); } if (rr_print) receipt_request_print(cms); } else if (operation == SMIME_VERIFY_RECEIPT) { if (CMS_verify_receipt(rcms, cms, other, store, flags) > 0) BIO_printf(bio_err, "Verification successful\n"); else { BIO_printf(bio_err, "Verification failure\n"); goto end; } } else { if (noout) { if (print) CMS_ContentInfo_print_ctx(out, cms, 0, NULL); } else if (outformat == FORMAT_SMIME) { if (to) BIO_printf(out, "To: %s%s", to, mime_eol); if (from) BIO_printf(out, "From: %s%s", from, mime_eol); if (subject) BIO_printf(out, "Subject: %s%s", subject, mime_eol); if (operation == SMIME_RESIGN) ret = SMIME_write_CMS(out, cms, indata, flags); else ret = SMIME_write_CMS(out, cms, in, flags); } else if (outformat == FORMAT_PEM) ret = PEM_write_bio_CMS_stream(out, cms, in, flags); else if (outformat == FORMAT_ASN1) ret = i2d_CMS_bio_stream(out, cms, in, flags); else { BIO_printf(bio_err, "Bad output format for CMS file\n"); goto end; } if (ret <= 0) { ret = 6; goto end; } } ret = 0; end: if (ret) ERR_print_errors(bio_err); if (need_rand) app_RAND_write_file(NULL); sk_X509_pop_free(encerts, X509_free); sk_X509_pop_free(other, X509_free); X509_VERIFY_PARAM_free(vpm); sk_OPENSSL_STRING_free(sksigners); sk_OPENSSL_STRING_free(skkeys); OPENSSL_free(secret_key); OPENSSL_free(secret_keyid); OPENSSL_free(pwri_tmp); ASN1_OBJECT_free(econtent_type); CMS_ReceiptRequest_free(rr); sk_OPENSSL_STRING_free(rr_to); sk_OPENSSL_STRING_free(rr_from); for (key_param = key_first; key_param;) { cms_key_param *tparam; sk_OPENSSL_STRING_free(key_param->param); tparam = key_param->next; OPENSSL_free(key_param); key_param = tparam; } X509_STORE_free(store); X509_free(cert); X509_free(recip); X509_free(signer); EVP_PKEY_free(key); CMS_ContentInfo_free(cms); CMS_ContentInfo_free(rcms); release_engine(e); BIO_free(rctin); BIO_free(in); BIO_free(indata); BIO_free_all(out); OPENSSL_free(passin); return (ret); }
int MAIN(int argc, char **argv) { ENGINE *e = NULL; int ret=1; X509_REQ *req=NULL; X509 *x=NULL,*xca=NULL; ASN1_OBJECT *objtmp; EVP_PKEY *Upkey=NULL,*CApkey=NULL; ASN1_INTEGER *sno = NULL; int i,num,badops=0; BIO *out=NULL; BIO *STDout=NULL; STACK_OF(ASN1_OBJECT) *trust = NULL, *reject = NULL; int informat,outformat,keyformat,CAformat,CAkeyformat; char *infile=NULL,*outfile=NULL,*keyfile=NULL,*CAfile=NULL; char *CAkeyfile=NULL,*CAserial=NULL; char *alias=NULL; int text=0,serial=0,subject=0,issuer=0,startdate=0,enddate=0; int next_serial=0; int subject_hash=0,issuer_hash=0,ocspid=0; int noout=0,sign_flag=0,CA_flag=0,CA_createserial=0,email=0; int ocsp_uri=0; int trustout=0,clrtrust=0,clrreject=0,aliasout=0,clrext=0; int C=0; int x509req=0,days=DEF_DAYS,modulus=0,pubkey=0; int pprint = 0; const char **pp; X509_STORE *ctx=NULL; X509_REQ *rq=NULL; int fingerprint=0; char buf[256]; const EVP_MD *md_alg,*digest=EVP_sha1(); CONF *extconf = NULL; char *extsect = NULL, *extfile = NULL, *passin = NULL, *passargin = NULL; int need_rand = 0; int checkend=0,checkoffset=0; unsigned long nmflag = 0, certflag = 0; #ifndef OPENSSL_NO_ENGINE char *engine=NULL; #endif reqfile=0; apps_startup(); if (bio_err == NULL) bio_err=BIO_new_fp(stderr,BIO_NOCLOSE); if (!load_config(bio_err, NULL)) goto end; STDout=BIO_new_fp(stdout,BIO_NOCLOSE); #ifdef OPENSSL_SYS_VMS { BIO *tmpbio = BIO_new(BIO_f_linebuffer()); STDout = BIO_push(tmpbio, STDout); } #endif informat=FORMAT_PEM; outformat=FORMAT_PEM; keyformat=FORMAT_PEM; CAformat=FORMAT_PEM; CAkeyformat=FORMAT_PEM; ctx=X509_STORE_new(); if (ctx == NULL) goto end; X509_STORE_set_verify_cb_func(ctx,callb); argc--; argv++; num=0; 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,"-keyform") == 0) { if (--argc < 1) goto bad; keyformat=str2fmt(*(++argv)); } else if (strcmp(*argv,"-req") == 0) { reqfile=1; need_rand = 1; } else if (strcmp(*argv,"-CAform") == 0) { if (--argc < 1) goto bad; CAformat=str2fmt(*(++argv)); } else if (strcmp(*argv,"-CAkeyform") == 0) { if (--argc < 1) goto bad; CAkeyformat=str2fmt(*(++argv)); } else if (strcmp(*argv,"-days") == 0) { if (--argc < 1) goto bad; days=atoi(*(++argv)); if (days == 0) { BIO_printf(STDout,"bad number of days\n"); goto bad; } } else if (strcmp(*argv,"-passin") == 0) { if (--argc < 1) goto bad; passargin= *(++argv); } else if (strcmp(*argv,"-extfile") == 0) { if (--argc < 1) goto bad; extfile= *(++argv); } else if (strcmp(*argv,"-extensions") == 0) { if (--argc < 1) goto bad; extsect= *(++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; outfile= *(++argv); } else if (strcmp(*argv,"-signkey") == 0) { if (--argc < 1) goto bad; keyfile= *(++argv); sign_flag= ++num; need_rand = 1; } else if (strcmp(*argv,"-CA") == 0) { if (--argc < 1) goto bad; CAfile= *(++argv); CA_flag= ++num; need_rand = 1; } else if (strcmp(*argv,"-CAkey") == 0) { if (--argc < 1) goto bad; CAkeyfile= *(++argv); } else if (strcmp(*argv,"-CAserial") == 0) { if (--argc < 1) goto bad; CAserial= *(++argv); } else if (strcmp(*argv,"-set_serial") == 0) { if (--argc < 1) goto bad; if (!(sno = s2i_ASN1_INTEGER(NULL, *(++argv)))) goto bad; } else if (strcmp(*argv,"-addtrust") == 0) { if (--argc < 1) goto bad; if (!(objtmp = OBJ_txt2obj(*(++argv), 0))) { BIO_printf(bio_err, "Invalid trust object value %s\n", *argv); goto bad; } if (!trust) trust = sk_ASN1_OBJECT_new_null(); sk_ASN1_OBJECT_push(trust, objtmp); trustout = 1; } else if (strcmp(*argv,"-addreject") == 0) { if (--argc < 1) goto bad; if (!(objtmp = OBJ_txt2obj(*(++argv), 0))) { BIO_printf(bio_err, "Invalid reject object value %s\n", *argv); goto bad; } if (!reject) reject = sk_ASN1_OBJECT_new_null(); sk_ASN1_OBJECT_push(reject, objtmp); trustout = 1; } else if (strcmp(*argv,"-setalias") == 0) { if (--argc < 1) goto bad; alias= *(++argv); trustout = 1; } else if (strcmp(*argv,"-certopt") == 0) { if (--argc < 1) goto bad; if (!set_cert_ex(&certflag, *(++argv))) goto bad; } else if (strcmp(*argv,"-nameopt") == 0) { if (--argc < 1) goto bad; if (!set_name_ex(&nmflag, *(++argv))) goto bad; } #ifndef OPENSSL_NO_ENGINE else if (strcmp(*argv,"-engine") == 0) { if (--argc < 1) goto bad; engine= *(++argv); } #endif else if (strcmp(*argv,"-C") == 0) C= ++num; else if (strcmp(*argv,"-email") == 0) email= ++num; else if (strcmp(*argv,"-ocsp_uri") == 0) ocsp_uri= ++num; else if (strcmp(*argv,"-serial") == 0) serial= ++num; else if (strcmp(*argv,"-next_serial") == 0) next_serial= ++num; else if (strcmp(*argv,"-modulus") == 0) modulus= ++num; else if (strcmp(*argv,"-pubkey") == 0) pubkey= ++num; else if (strcmp(*argv,"-x509toreq") == 0) x509req= ++num; else if (strcmp(*argv,"-text") == 0) text= ++num; else if (strcmp(*argv,"-hash") == 0 || strcmp(*argv,"-subject_hash") == 0) subject_hash= ++num; else if (strcmp(*argv,"-issuer_hash") == 0) issuer_hash= ++num; else if (strcmp(*argv,"-subject") == 0) subject= ++num; else if (strcmp(*argv,"-issuer") == 0) issuer= ++num; else if (strcmp(*argv,"-fingerprint") == 0) fingerprint= ++num; else if (strcmp(*argv,"-dates") == 0) { startdate= ++num; enddate= ++num; } else if (strcmp(*argv,"-purpose") == 0) pprint= ++num; else if (strcmp(*argv,"-startdate") == 0) startdate= ++num; else if (strcmp(*argv,"-enddate") == 0) enddate= ++num; else if (strcmp(*argv,"-checkend") == 0) { if (--argc < 1) goto bad; checkoffset=atoi(*(++argv)); checkend=1; } else if (strcmp(*argv,"-noout") == 0) noout= ++num; else if (strcmp(*argv,"-trustout") == 0) trustout= 1; else if (strcmp(*argv,"-clrtrust") == 0) clrtrust= ++num; else if (strcmp(*argv,"-clrreject") == 0) clrreject= ++num; else if (strcmp(*argv,"-alias") == 0) aliasout= ++num; else if (strcmp(*argv,"-CAcreateserial") == 0) CA_createserial= ++num; else if (strcmp(*argv,"-clrext") == 0) clrext = 1; #if 1 /* stay backwards-compatible with 0.9.5; this should go away soon */ else if (strcmp(*argv,"-crlext") == 0) { BIO_printf(bio_err,"use -clrext instead of -crlext\n"); clrext = 1; } #endif else if (strcmp(*argv,"-ocspid") == 0) ocspid= ++num; else if ((md_alg=EVP_get_digestbyname(*argv + 1))) { /* ok */ digest=md_alg; } else { BIO_printf(bio_err,"unknown option %s\n",*argv); badops=1; break; } argc--; argv++; } if (badops) { bad: for (pp=x509_usage; (*pp != NULL); pp++) BIO_printf(bio_err,"%s",*pp); goto end; } #ifndef OPENSSL_NO_ENGINE e = setup_engine(bio_err, engine, 0); #endif if (need_rand) app_RAND_load_file(NULL, bio_err, 0); ERR_load_crypto_strings(); if (!app_passwd(bio_err, passargin, NULL, &passin, NULL)) { BIO_printf(bio_err, "Error getting password\n"); goto end; } if (!X509_STORE_set_default_paths(ctx)) { ERR_print_errors(bio_err); goto end; } if ((CAkeyfile == NULL) && (CA_flag) && (CAformat == FORMAT_PEM)) { CAkeyfile=CAfile; } else if ((CA_flag) && (CAkeyfile == NULL)) { BIO_printf(bio_err,"need to specify a CAkey if using the CA command\n"); goto end; } if (extfile) { long errorline = -1; X509V3_CTX ctx2; extconf = NCONF_new(NULL); if (!NCONF_load(extconf, extfile,&errorline)) { if (errorline <= 0) BIO_printf(bio_err, "error loading the config file '%s'\n", extfile); else BIO_printf(bio_err, "error on line %ld of config file '%s'\n" ,errorline,extfile); goto end; } if (!extsect) { extsect = NCONF_get_string(extconf, "default", "extensions"); if (!extsect) { ERR_clear_error(); extsect = "default"; } } X509V3_set_ctx_test(&ctx2); X509V3_set_nconf(&ctx2, extconf); if (!X509V3_EXT_add_nconf(extconf, &ctx2, extsect, NULL)) { BIO_printf(bio_err, "Error Loading extension section %s\n", extsect); ERR_print_errors(bio_err); goto end; } } if (reqfile) { EVP_PKEY *pkey; BIO *in; if (!sign_flag && !CA_flag) { BIO_printf(bio_err,"We need a private key to sign with\n"); goto end; } in=BIO_new(BIO_s_file()); if (in == NULL) { ERR_print_errors(bio_err); goto end; } if (infile == NULL) BIO_set_fp(in,stdin,BIO_NOCLOSE|BIO_FP_TEXT); else { if (BIO_read_filename(in,infile) <= 0) { perror(infile); BIO_free(in); goto end; } } req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL); BIO_free(in); if (req == NULL) { ERR_print_errors(bio_err); goto end; } if ( (req->req_info == NULL) || (req->req_info->pubkey == NULL) || (req->req_info->pubkey->public_key == NULL) || (req->req_info->pubkey->public_key->data == NULL)) { BIO_printf(bio_err,"The certificate request appears to corrupted\n"); BIO_printf(bio_err,"It does not contain a public key\n"); goto end; } if ((pkey=X509_REQ_get_pubkey(req)) == NULL) { BIO_printf(bio_err,"error unpacking public key\n"); goto end; } i=X509_REQ_verify(req,pkey); EVP_PKEY_free(pkey); if (i < 0) { BIO_printf(bio_err,"Signature verification error\n"); ERR_print_errors(bio_err); goto end; } if (i == 0) { BIO_printf(bio_err,"Signature did not match the certificate request\n"); goto end; } else BIO_printf(bio_err,"Signature ok\n"); print_name(bio_err, "subject=", X509_REQ_get_subject_name(req), nmflag); if ((x=X509_new()) == NULL) goto end; if (sno == NULL) { sno = ASN1_INTEGER_new(); if (!sno || !rand_serial(NULL, sno)) goto end; if (!X509_set_serialNumber(x, sno)) goto end; ASN1_INTEGER_free(sno); sno = NULL; } else if (!X509_set_serialNumber(x, sno)) goto end; if (!X509_set_issuer_name(x,req->req_info->subject)) goto end; if (!X509_set_subject_name(x,req->req_info->subject)) goto end; X509_gmtime_adj(X509_get_notBefore(x),0); X509_gmtime_adj(X509_get_notAfter(x),(long)60*60*24*days); pkey = X509_REQ_get_pubkey(req); X509_set_pubkey(x,pkey); EVP_PKEY_free(pkey); } else x=load_cert(bio_err,infile,informat,NULL,e,"Certificate"); if (x == NULL) goto end; if (CA_flag) { xca=load_cert(bio_err,CAfile,CAformat,NULL,e,"CA Certificate"); if (xca == NULL) goto end; } if (!noout || text || next_serial) { OBJ_create("2.99999.3", "SET.ex3","SET x509v3 extension 3"); out=BIO_new(BIO_s_file()); if (out == NULL) { ERR_print_errors(bio_err); goto end; } if (outfile == NULL) { BIO_set_fp(out,stdout,BIO_NOCLOSE); #ifdef OPENSSL_SYS_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 (alias) X509_alias_set1(x, (unsigned char *)alias, -1); if (clrtrust) X509_trust_clear(x); if (clrreject) X509_reject_clear(x); if (trust) { for (i = 0; i < sk_ASN1_OBJECT_num(trust); i++) { objtmp = sk_ASN1_OBJECT_value(trust, i); X509_add1_trust_object(x, objtmp); } } if (reject) { for (i = 0; i < sk_ASN1_OBJECT_num(reject); i++) { objtmp = sk_ASN1_OBJECT_value(reject, i); X509_add1_reject_object(x, objtmp); } } if (num) { for (i=1; i<=num; i++) { if (issuer == i) { print_name(STDout, "issuer= ", X509_get_issuer_name(x), nmflag); } else if (subject == i) { print_name(STDout, "subject= ", X509_get_subject_name(x), nmflag); } else if (serial == i) { BIO_printf(STDout,"serial="); i2a_ASN1_INTEGER(STDout, X509_get_serialNumber(x)); BIO_printf(STDout,"\n"); } else if (next_serial == i) { BIGNUM *bnser; ASN1_INTEGER *ser; ser = X509_get_serialNumber(x); bnser = ASN1_INTEGER_to_BN(ser, NULL); if (!bnser) goto end; if (!BN_add_word(bnser, 1)) goto end; ser = BN_to_ASN1_INTEGER(bnser, NULL); if (!ser) goto end; BN_free(bnser); i2a_ASN1_INTEGER(out, ser); ASN1_INTEGER_free(ser); BIO_puts(out, "\n"); } else if ((email == i) || (ocsp_uri == i)) { int j; STACK *emlst; if (email == i) emlst = X509_get1_email(x); else emlst = X509_get1_ocsp(x); for (j = 0; j < sk_num(emlst); j++) BIO_printf(STDout, "%s\n", sk_value(emlst, j)); X509_email_free(emlst); } else if (aliasout == i) { unsigned char *alstr; alstr = X509_alias_get0(x, NULL); if (alstr) BIO_printf(STDout,"%s\n", alstr); else BIO_puts(STDout,"<No Alias>\n"); } else if (subject_hash == i) { BIO_printf(STDout,"%08lx\n",X509_subject_name_hash(x)); } else if (issuer_hash == i) { BIO_printf(STDout,"%08lx\n",X509_issuer_name_hash(x)); } else if (pprint == i) { X509_PURPOSE *ptmp; int j; BIO_printf(STDout, "Certificate purposes:\n"); for (j = 0; j < X509_PURPOSE_get_count(); j++) { ptmp = X509_PURPOSE_get0(j); purpose_print(STDout, x, ptmp); } } else if (modulus == i) { EVP_PKEY *pkey; pkey=X509_get_pubkey(x); if (pkey == NULL) { BIO_printf(bio_err,"Modulus=unavailable\n"); ERR_print_errors(bio_err); goto end; } BIO_printf(STDout,"Modulus="); #ifndef OPENSSL_NO_RSA if (pkey->type == EVP_PKEY_RSA) BN_print(STDout,pkey->pkey.rsa->n); else #endif #ifndef OPENSSL_NO_DSA if (pkey->type == EVP_PKEY_DSA) BN_print(STDout,pkey->pkey.dsa->pub_key); else #endif BIO_printf(STDout,"Wrong Algorithm type"); BIO_printf(STDout,"\n"); EVP_PKEY_free(pkey); } else if (pubkey == i) { EVP_PKEY *pkey; pkey=X509_get_pubkey(x); if (pkey == NULL) { BIO_printf(bio_err,"Error getting public key\n"); ERR_print_errors(bio_err); goto end; } PEM_write_bio_PUBKEY(STDout, pkey); EVP_PKEY_free(pkey); } else if (C == i) { unsigned char *d; char *m; int y,z; X509_NAME_oneline(X509_get_subject_name(x), buf,sizeof buf); BIO_printf(STDout,"/* subject:%s */\n",buf); m=X509_NAME_oneline( X509_get_issuer_name(x),buf, sizeof buf); BIO_printf(STDout,"/* issuer :%s */\n",buf); z=i2d_X509(x,NULL); m=OPENSSL_malloc(z); d=(unsigned char *)m; z=i2d_X509_NAME(X509_get_subject_name(x),&d); BIO_printf(STDout,"unsigned char XXX_subject_name[%d]={\n",z); d=(unsigned char *)m; for (y=0; y<z; y++) { BIO_printf(STDout,"0x%02X,",d[y]); if ((y & 0x0f) == 0x0f) BIO_printf(STDout,"\n"); } if (y%16 != 0) BIO_printf(STDout,"\n"); BIO_printf(STDout,"};\n"); z=i2d_X509_PUBKEY(X509_get_X509_PUBKEY(x),&d); BIO_printf(STDout,"unsigned char XXX_public_key[%d]={\n",z); d=(unsigned char *)m; for (y=0; y<z; y++) { BIO_printf(STDout,"0x%02X,",d[y]); if ((y & 0x0f) == 0x0f) BIO_printf(STDout,"\n"); } if (y%16 != 0) BIO_printf(STDout,"\n"); BIO_printf(STDout,"};\n"); z=i2d_X509(x,&d); BIO_printf(STDout,"unsigned char XXX_certificate[%d]={\n",z); d=(unsigned char *)m; for (y=0; y<z; y++) { BIO_printf(STDout,"0x%02X,",d[y]); if ((y & 0x0f) == 0x0f) BIO_printf(STDout,"\n"); } if (y%16 != 0) BIO_printf(STDout,"\n"); BIO_printf(STDout,"};\n"); OPENSSL_free(m); } else if (text == i) { X509_print_ex(out,x,nmflag, certflag); } else if (startdate == i) { BIO_puts(STDout,"notBefore="); ASN1_TIME_print(STDout,X509_get_notBefore(x)); BIO_puts(STDout,"\n"); } else if (enddate == i) { BIO_puts(STDout,"notAfter="); ASN1_TIME_print(STDout,X509_get_notAfter(x)); BIO_puts(STDout,"\n"); } else if (fingerprint == i) { int j; unsigned int n; unsigned char md[EVP_MAX_MD_SIZE]; if (!X509_digest(x,digest,md,&n)) { BIO_printf(bio_err,"out of memory\n"); goto end; } BIO_printf(STDout,"%s Fingerprint=", OBJ_nid2sn(EVP_MD_type(digest))); for (j=0; j<(int)n; j++) { BIO_printf(STDout,"%02X%c",md[j], (j+1 == (int)n) ?'\n':':'); } } /* should be in the library */ else if ((sign_flag == i) && (x509req == 0)) { BIO_printf(bio_err,"Getting Private key\n"); if (Upkey == NULL) { Upkey=load_key(bio_err, keyfile, keyformat, 0, passin, e, "Private key"); if (Upkey == NULL) goto end; } #ifndef OPENSSL_NO_DSA if (Upkey->type == EVP_PKEY_DSA) digest=EVP_dss1(); #endif #ifndef OPENSSL_NO_ECDSA if (Upkey->type == EVP_PKEY_EC) digest=EVP_ecdsa(); #endif assert(need_rand); if (!sign(x,Upkey,days,clrext,digest, extconf, extsect)) goto end; } else if (CA_flag == i) { BIO_printf(bio_err,"Getting CA Private Key\n"); if (CAkeyfile != NULL) { CApkey=load_key(bio_err, CAkeyfile, CAkeyformat, 0, passin, e, "CA Private Key"); if (CApkey == NULL) goto end; } #ifndef OPENSSL_NO_DSA if (CApkey->type == EVP_PKEY_DSA) digest=EVP_dss1(); #endif #ifndef OPENSSL_NO_ECDSA if (CApkey->type == EVP_PKEY_EC) digest = EVP_ecdsa(); #endif assert(need_rand); if (!x509_certify(ctx,CAfile,digest,x,xca, CApkey, CAserial,CA_createserial,days, clrext, extconf, extsect, sno)) goto end; } else if (x509req == i) { EVP_PKEY *pk; BIO_printf(bio_err,"Getting request Private Key\n"); if (keyfile == NULL) { BIO_printf(bio_err,"no request key file specified\n"); goto end; } else { pk=load_key(bio_err, keyfile, FORMAT_PEM, 0, passin, e, "request key"); if (pk == NULL) goto end; } BIO_printf(bio_err,"Generating certificate request\n"); #ifndef OPENSSL_NO_DSA if (pk->type == EVP_PKEY_DSA) digest=EVP_dss1(); #endif #ifndef OPENSSL_NO_ECDSA if (pk->type == EVP_PKEY_EC) digest=EVP_ecdsa(); #endif rq=X509_to_X509_REQ(x,pk,digest); EVP_PKEY_free(pk); if (rq == NULL) { ERR_print_errors(bio_err); goto end; } if (!noout) { X509_REQ_print(out,rq); PEM_write_bio_X509_REQ(out,rq); } noout=1; } else if (ocspid == i) { X509_ocspid_print(out, x); } } } if (checkend) { time_t tcheck=time(NULL) + checkoffset; if (X509_cmp_time(X509_get_notAfter(x), &tcheck) < 0) { BIO_printf(out,"Certificate will expire\n"); ret=1; } else { BIO_printf(out,"Certificate will not expire\n"); ret=0; } goto end; } if (noout) { ret=0; goto end; } if (outformat == FORMAT_ASN1) i=i2d_X509_bio(out,x); else if (outformat == FORMAT_PEM) { if (trustout) i=PEM_write_bio_X509_AUX(out,x); else i=PEM_write_bio_X509(out,x); } else if (outformat == FORMAT_NETSCAPE) { ASN1_HEADER ah; ASN1_OCTET_STRING os; os.data=(unsigned char *)NETSCAPE_CERT_HDR; os.length=strlen(NETSCAPE_CERT_HDR); ah.header= &os; ah.data=(char *)x; ah.meth=X509_asn1_meth(); i=ASN1_i2d_bio_of(ASN1_HEADER,i2d_ASN1_HEADER,out,&ah); } else { BIO_printf(bio_err,"bad output format specified for outfile\n"); goto end; } if (!i) { BIO_printf(bio_err,"unable to write certificate\n"); ERR_print_errors(bio_err); goto end; } ret=0; end: if (need_rand) app_RAND_write_file(NULL, bio_err); OBJ_cleanup(); NCONF_free(extconf); BIO_free_all(out); BIO_free_all(STDout); X509_STORE_free(ctx); X509_REQ_free(req); X509_free(x); X509_free(xca); EVP_PKEY_free(Upkey); EVP_PKEY_free(CApkey); X509_REQ_free(rq); ASN1_INTEGER_free(sno); sk_ASN1_OBJECT_pop_free(trust, ASN1_OBJECT_free); sk_ASN1_OBJECT_pop_free(reject, ASN1_OBJECT_free); if (passin) OPENSSL_free(passin); apps_shutdown(); OPENSSL_EXIT(ret); }
static ASN1_TYPE * asn1_str2type(const char *str, int format, int utype) { ASN1_TYPE *atmp = NULL; CONF_VALUE vtmp; unsigned char *rdata; long rdlen; int no_unused = 1; if (!(atmp = ASN1_TYPE_new())) { ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); return NULL; } if (!str) str = ""; switch (utype) { case V_ASN1_NULL: if (str && *str) { ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_NULL_VALUE); goto bad_form; } break; case V_ASN1_BOOLEAN: if (format != ASN1_GEN_FORMAT_ASCII) { ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_NOT_ASCII_FORMAT); goto bad_form; } vtmp.name = NULL; vtmp.section = NULL; vtmp.value = (char *)str; if (!X509V3_get_value_bool(&vtmp, &atmp->value.boolean)) { ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_BOOLEAN); goto bad_str; } break; case V_ASN1_INTEGER: case V_ASN1_ENUMERATED: if (format != ASN1_GEN_FORMAT_ASCII) { ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_INTEGER_NOT_ASCII_FORMAT); goto bad_form; } if (!(atmp->value.integer = s2i_ASN1_INTEGER(NULL, (char *)str))) { ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_INTEGER); goto bad_str; } break; case V_ASN1_OBJECT: if (format != ASN1_GEN_FORMAT_ASCII) { ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_OBJECT_NOT_ASCII_FORMAT); goto bad_form; } if (!(atmp->value.object = OBJ_txt2obj(str, 0))) { ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_OBJECT); goto bad_str; } break; case V_ASN1_UTCTIME: case V_ASN1_GENERALIZEDTIME: if (format != ASN1_GEN_FORMAT_ASCII) { ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_TIME_NOT_ASCII_FORMAT); goto bad_form; } if (!(atmp->value.asn1_string = ASN1_STRING_new())) { ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); goto bad_str; } if (!ASN1_STRING_set(atmp->value.asn1_string, str, -1)) { ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); goto bad_str; } atmp->value.asn1_string->type = utype; if (!ASN1_TIME_check(atmp->value.asn1_string)) { ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_TIME_VALUE); goto bad_str; } break; case V_ASN1_BMPSTRING: case V_ASN1_PRINTABLESTRING: case V_ASN1_IA5STRING: case V_ASN1_T61STRING: case V_ASN1_UTF8STRING: case V_ASN1_VISIBLESTRING: case V_ASN1_UNIVERSALSTRING: case V_ASN1_GENERALSTRING: case V_ASN1_NUMERICSTRING: if (format == ASN1_GEN_FORMAT_ASCII) format = MBSTRING_ASC; else if (format == ASN1_GEN_FORMAT_UTF8) format = MBSTRING_UTF8; else { ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_FORMAT); goto bad_form; } if (ASN1_mbstring_copy(&atmp->value.asn1_string, (unsigned char *)str, -1, format, ASN1_tag2bit(utype)) <= 0) { ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); goto bad_str; } break; case V_ASN1_BIT_STRING: case V_ASN1_OCTET_STRING: if (!(atmp->value.asn1_string = ASN1_STRING_new())) { ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); goto bad_form; } if (format == ASN1_GEN_FORMAT_HEX) { if (!(rdata = string_to_hex((char *)str, &rdlen))) { ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_HEX); goto bad_str; } atmp->value.asn1_string->data = rdata; atmp->value.asn1_string->length = rdlen; atmp->value.asn1_string->type = utype; } else if (format == ASN1_GEN_FORMAT_ASCII) ASN1_STRING_set(atmp->value.asn1_string, str, -1); else if ((format == ASN1_GEN_FORMAT_BITLIST) && (utype == V_ASN1_BIT_STRING)) { if (!CONF_parse_list(str, ',', 1, bitstr_cb, atmp->value.bit_string)) { ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_LIST_ERROR); goto bad_str; } no_unused = 0; } else { ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_BITSTRING_FORMAT); goto bad_form; } if ((utype == V_ASN1_BIT_STRING) && no_unused) { atmp->value.asn1_string->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); atmp->value.asn1_string->flags |= ASN1_STRING_FLAG_BITS_LEFT; } break; default: ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_UNSUPPORTED_TYPE); goto bad_str; break; } atmp->type = utype; return atmp; bad_str: ERR_asprintf_error_data("string=%s", str); bad_form: ASN1_TYPE_free(atmp); return NULL; }
CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy) { struct negotiatedata *neg_ctx = proxy?&conn->data->state.proxyneg: &conn->data->state.negotiate; char *encoded = NULL; size_t len; char *userp; #ifdef HAVE_SPNEGO /* Handle SPNEGO */ if(checkprefix("Negotiate", neg_ctx->protocol)) { ASN1_OBJECT * object = NULL; int rc = 1; unsigned char * spnegoToken = NULL; size_t spnegoTokenLength = 0; unsigned char * responseToken = NULL; size_t responseTokenLength = 0; responseToken = malloc(neg_ctx->output_token.length); if(responseToken == NULL) return CURLE_OUT_OF_MEMORY; memcpy(responseToken, neg_ctx->output_token.value, neg_ctx->output_token.length); responseTokenLength = neg_ctx->output_token.length; object=OBJ_txt2obj ("1.2.840.113554.1.2.2", 1); if(!makeSpnegoInitialToken (object, responseToken, responseTokenLength, &spnegoToken, &spnegoTokenLength)) { free(responseToken); responseToken = NULL; infof(conn->data, "Make SPNEGO Initial Token failed\n"); } else { free(responseToken); responseToken = NULL; free(neg_ctx->output_token.value); neg_ctx->output_token.value = malloc(spnegoTokenLength); if(neg_ctx->output_token.value == NULL) { free(spnegoToken); spnegoToken = NULL; return CURLE_OUT_OF_MEMORY; } memcpy(neg_ctx->output_token.value, spnegoToken,spnegoTokenLength); neg_ctx->output_token.length = spnegoTokenLength; free(spnegoToken); spnegoToken = NULL; infof(conn->data, "Make SPNEGO Initial Token succeeded\n"); } } #endif len = Curl_base64_encode(conn->data, neg_ctx->output_token.value, neg_ctx->output_token.length, &encoded); if(len == 0) return CURLE_OUT_OF_MEMORY; userp = aprintf("%sAuthorization: %s %s\r\n", proxy ? "Proxy-" : "", neg_ctx->protocol, encoded); if(proxy) conn->allocptr.proxyuserpwd = userp; else conn->allocptr.userpwd = userp; free(encoded); Curl_cleanup_negotiate (conn->data); return (userp == NULL) ? CURLE_OUT_OF_MEMORY : CURLE_OK; }
int MAIN(int argc, char **argv) { ENGINE *e = NULL; int operation = 0; int ret = 0; char **args; const char *inmode = "r", *outmode = "w"; char *infile = NULL, *outfile = NULL, *rctfile = NULL; char *signerfile = NULL, *recipfile = NULL; STACK_OF(OPENSSL_STRING) *sksigners = NULL, *skkeys = NULL; char *certfile = NULL, *keyfile = NULL, *contfile=NULL; char *certsoutfile = NULL; const EVP_CIPHER *cipher = NULL; CMS_ContentInfo *cms = NULL, *rcms = NULL; X509_STORE *store = NULL; X509 *cert = NULL, *recip = NULL, *signer = NULL; EVP_PKEY *key = NULL; STACK_OF(X509) *encerts = NULL, *other = NULL; BIO *in = NULL, *out = NULL, *indata = NULL, *rctin = NULL; int badarg = 0; int flags = CMS_DETACHED, noout = 0, print = 0; int verify_retcode = 0; int rr_print = 0, rr_allorfirst = -1; STACK_OF(OPENSSL_STRING) *rr_to = NULL, *rr_from = NULL; CMS_ReceiptRequest *rr = NULL; char *to = NULL, *from = NULL, *subject = NULL; char *CAfile = NULL, *CApath = NULL; char *passargin = NULL, *passin = NULL; char *inrand = NULL; int need_rand = 0; const EVP_MD *sign_md = NULL; int informat = FORMAT_SMIME, outformat = FORMAT_SMIME; int rctformat = FORMAT_SMIME, keyform = FORMAT_PEM; #ifndef OPENSSL_NO_ENGINE char *engine=NULL; #endif unsigned char *secret_key = NULL, *secret_keyid = NULL; size_t secret_keylen = 0, secret_keyidlen = 0; ASN1_OBJECT *econtent_type = NULL; X509_VERIFY_PARAM *vpm = NULL; args = argv + 1; ret = 1; 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); } if (!load_config(bio_err, NULL)) goto end; while (!badarg && *args && *args[0] == '-') { if (!strcmp (*args, "-encrypt")) operation = SMIME_ENCRYPT; else if (!strcmp (*args, "-decrypt")) operation = SMIME_DECRYPT; else if (!strcmp (*args, "-sign")) operation = SMIME_SIGN; else if (!strcmp (*args, "-sign_receipt")) operation = SMIME_SIGN_RECEIPT; else if (!strcmp (*args, "-resign")) operation = SMIME_RESIGN; else if (!strcmp (*args, "-verify")) operation = SMIME_VERIFY; else if (!strcmp (*args, "-verify_retcode")) verify_retcode = 1; else if (!strcmp(*args,"-verify_receipt")) { operation = SMIME_VERIFY_RECEIPT; if (!args[1]) goto argerr; args++; rctfile = *args; } else if (!strcmp (*args, "-cmsout")) operation = SMIME_CMSOUT; else if (!strcmp (*args, "-data_out")) operation = SMIME_DATAOUT; else if (!strcmp (*args, "-data_create")) operation = SMIME_DATA_CREATE; else if (!strcmp (*args, "-digest_verify")) operation = SMIME_DIGEST_VERIFY; else if (!strcmp (*args, "-digest_create")) operation = SMIME_DIGEST_CREATE; else if (!strcmp (*args, "-compress")) operation = SMIME_COMPRESS; else if (!strcmp (*args, "-uncompress")) operation = SMIME_UNCOMPRESS; else if (!strcmp (*args, "-EncryptedData_decrypt")) operation = SMIME_ENCRYPTED_DECRYPT; else if (!strcmp (*args, "-EncryptedData_encrypt")) operation = SMIME_ENCRYPTED_ENCRYPT; #ifndef OPENSSL_NO_DES else if (!strcmp (*args, "-des3")) cipher = EVP_des_ede3_cbc(); else if (!strcmp (*args, "-des")) cipher = EVP_des_cbc(); #endif #ifndef OPENSSL_NO_SEED else if (!strcmp (*args, "-seed")) cipher = EVP_seed_cbc(); #endif #ifndef OPENSSL_NO_RC2 else if (!strcmp (*args, "-rc2-40")) cipher = EVP_rc2_40_cbc(); else if (!strcmp (*args, "-rc2-128")) cipher = EVP_rc2_cbc(); else if (!strcmp (*args, "-rc2-64")) cipher = EVP_rc2_64_cbc(); #endif #ifndef OPENSSL_NO_AES else if (!strcmp(*args,"-aes128")) cipher = EVP_aes_128_cbc(); else if (!strcmp(*args,"-aes192")) cipher = EVP_aes_192_cbc(); else if (!strcmp(*args,"-aes256")) cipher = EVP_aes_256_cbc(); #endif #ifndef OPENSSL_NO_CAMELLIA else if (!strcmp(*args,"-camellia128")) cipher = EVP_camellia_128_cbc(); else if (!strcmp(*args,"-camellia192")) cipher = EVP_camellia_192_cbc(); else if (!strcmp(*args,"-camellia256")) cipher = EVP_camellia_256_cbc(); #endif else if (!strcmp (*args, "-debug_decrypt")) flags |= CMS_DEBUG_DECRYPT; else if (!strcmp (*args, "-text")) flags |= CMS_TEXT; else if (!strcmp (*args, "-nointern")) flags |= CMS_NOINTERN; else if (!strcmp (*args, "-noverify") || !strcmp (*args, "-no_signer_cert_verify")) flags |= CMS_NO_SIGNER_CERT_VERIFY; else if (!strcmp (*args, "-nocerts")) flags |= CMS_NOCERTS; else if (!strcmp (*args, "-noattr")) flags |= CMS_NOATTR; else if (!strcmp (*args, "-nodetach")) flags &= ~CMS_DETACHED; else if (!strcmp (*args, "-nosmimecap")) flags |= CMS_NOSMIMECAP; else if (!strcmp (*args, "-binary")) flags |= CMS_BINARY; else if (!strcmp (*args, "-keyid")) flags |= CMS_USE_KEYID; else if (!strcmp (*args, "-nosigs")) flags |= CMS_NOSIGS; else if (!strcmp (*args, "-no_content_verify")) flags |= CMS_NO_CONTENT_VERIFY; else if (!strcmp (*args, "-no_attr_verify")) flags |= CMS_NO_ATTR_VERIFY; else if (!strcmp (*args, "-stream")) flags |= CMS_STREAM; else if (!strcmp (*args, "-indef")) flags |= CMS_STREAM; else if (!strcmp (*args, "-noindef")) flags &= ~CMS_STREAM; else if (!strcmp (*args, "-nooldmime")) flags |= CMS_NOOLDMIMETYPE; else if (!strcmp (*args, "-crlfeol")) flags |= CMS_CRLFEOL; else if (!strcmp (*args, "-noout")) noout = 1; else if (!strcmp (*args, "-receipt_request_print")) rr_print = 1; else if (!strcmp (*args, "-receipt_request_all")) rr_allorfirst = 0; else if (!strcmp (*args, "-receipt_request_first")) rr_allorfirst = 1; else if (!strcmp(*args,"-receipt_request_from")) { if (!args[1]) goto argerr; args++; if (!rr_from) rr_from = sk_OPENSSL_STRING_new_null(); sk_OPENSSL_STRING_push(rr_from, *args); } else if (!strcmp(*args,"-receipt_request_to")) { if (!args[1]) goto argerr; args++; if (!rr_to) rr_to = sk_OPENSSL_STRING_new_null(); sk_OPENSSL_STRING_push(rr_to, *args); } else if (!strcmp (*args, "-print")) { noout = 1; print = 1; } else if (!strcmp(*args,"-secretkey")) { long ltmp; if (!args[1]) goto argerr; args++; secret_key = string_to_hex(*args, <mp); if (!secret_key) { BIO_printf(bio_err, "Invalid key %s\n", *args); goto argerr; } secret_keylen = (size_t)ltmp; } else if (!strcmp(*args,"-secretkeyid")) { long ltmp; if (!args[1]) goto argerr; args++; secret_keyid = string_to_hex(*args, <mp); if (!secret_keyid) { BIO_printf(bio_err, "Invalid id %s\n", *args); goto argerr; } secret_keyidlen = (size_t)ltmp; } else if (!strcmp(*args,"-econtent_type")) { if (!args[1]) goto argerr; args++; econtent_type = OBJ_txt2obj(*args, 0); if (!econtent_type) { BIO_printf(bio_err, "Invalid OID %s\n", *args); goto argerr; } } else if (!strcmp(*args,"-rand")) { if (!args[1]) goto argerr; args++; inrand = *args; need_rand = 1; } #ifndef OPENSSL_NO_ENGINE else if (!strcmp(*args,"-engine")) { if (!args[1]) goto argerr; engine = *++args; } #endif else if (!strcmp(*args,"-passin")) { if (!args[1]) goto argerr; passargin = *++args; } else if (!strcmp (*args, "-to")) { if (!args[1]) goto argerr; to = *++args; } else if (!strcmp (*args, "-from")) { if (!args[1]) goto argerr; from = *++args; } else if (!strcmp (*args, "-subject")) { if (!args[1]) goto argerr; subject = *++args; } else if (!strcmp (*args, "-signer")) { if (!args[1]) goto argerr; /* If previous -signer argument add signer to list */ if (signerfile) { if (!sksigners) sksigners = sk_OPENSSL_STRING_new_null(); sk_OPENSSL_STRING_push(sksigners, signerfile); if (!keyfile) keyfile = signerfile; if (!skkeys) skkeys = sk_OPENSSL_STRING_new_null(); sk_OPENSSL_STRING_push(skkeys, keyfile); keyfile = NULL; } signerfile = *++args; } else if (!strcmp (*args, "-recip")) { if (!args[1]) goto argerr; recipfile = *++args; } else if (!strcmp (*args, "-certsout")) { if (!args[1]) goto argerr; certsoutfile = *++args; } else if (!strcmp (*args, "-md")) { if (!args[1]) goto argerr; sign_md = EVP_get_digestbyname(*++args); if (sign_md == NULL) { BIO_printf(bio_err, "Unknown digest %s\n", *args); goto argerr; } } else if (!strcmp (*args, "-inkey")) { if (!args[1]) goto argerr; /* If previous -inkey arument add signer to list */ if (keyfile) { if (!signerfile) { BIO_puts(bio_err, "Illegal -inkey without -signer\n"); goto argerr; } if (!sksigners) sksigners = sk_OPENSSL_STRING_new_null(); sk_OPENSSL_STRING_push(sksigners, signerfile); signerfile = NULL; if (!skkeys) skkeys = sk_OPENSSL_STRING_new_null(); sk_OPENSSL_STRING_push(skkeys, keyfile); } keyfile = *++args; } else if (!strcmp (*args, "-keyform")) { if (!args[1]) goto argerr; keyform = str2fmt(*++args); } else if (!strcmp (*args, "-rctform")) { if (!args[1]) goto argerr; rctformat = str2fmt(*++args); } else if (!strcmp (*args, "-certfile")) { if (!args[1]) goto argerr; certfile = *++args; } else if (!strcmp (*args, "-CAfile")) { if (!args[1]) goto argerr; CAfile = *++args; } else if (!strcmp (*args, "-CApath")) { if (!args[1]) goto argerr; CApath = *++args; } else if (!strcmp (*args, "-in")) { if (!args[1]) goto argerr; infile = *++args; } else if (!strcmp (*args, "-inform")) { if (!args[1]) goto argerr; informat = str2fmt(*++args); } else if (!strcmp (*args, "-outform")) { if (!args[1]) goto argerr; outformat = str2fmt(*++args); } else if (!strcmp (*args, "-out")) { if (!args[1]) goto argerr; outfile = *++args; } else if (!strcmp (*args, "-content")) { if (!args[1]) goto argerr; contfile = *++args; } else if (args_verify(&args, NULL, &badarg, bio_err, &vpm)) continue; else if ((cipher = EVP_get_cipherbyname(*args + 1)) == NULL) badarg = 1; args++; } if (((rr_allorfirst != -1) || rr_from) && !rr_to) { BIO_puts(bio_err, "No Signed Receipts Recipients\n"); goto argerr; } if (!(operation & SMIME_SIGNERS) && (rr_to || rr_from)) { BIO_puts(bio_err, "Signed receipts only allowed with -sign\n"); goto argerr; } if (!(operation & SMIME_SIGNERS) && (skkeys || sksigners)) { BIO_puts(bio_err, "Multiple signers or keys not allowed\n"); goto argerr; } if (operation & SMIME_SIGNERS) { if (keyfile && !signerfile) { BIO_puts(bio_err, "Illegal -inkey without -signer\n"); goto argerr; } /* Check to see if any final signer needs to be appended */ if (signerfile) { if (!sksigners) sksigners = sk_OPENSSL_STRING_new_null(); sk_OPENSSL_STRING_push(sksigners, signerfile); if (!skkeys) skkeys = sk_OPENSSL_STRING_new_null(); if (!keyfile) keyfile = signerfile; sk_OPENSSL_STRING_push(skkeys, keyfile); } if (!sksigners) { BIO_printf(bio_err, "No signer certificate specified\n"); badarg = 1; } signerfile = NULL; keyfile = NULL; need_rand = 1; } else if (operation == SMIME_DECRYPT) { if (!recipfile && !keyfile && !secret_key) { BIO_printf(bio_err, "No recipient certificate or key specified\n"); badarg = 1; } } else if (operation == SMIME_ENCRYPT) { if (!*args && !secret_key) { BIO_printf(bio_err, "No recipient(s) certificate(s) specified\n"); badarg = 1; } need_rand = 1; } else if (!operation) badarg = 1; if (badarg) { argerr: BIO_printf (bio_err, "Usage cms [options] cert.pem ...\n"); BIO_printf (bio_err, "where options are\n"); BIO_printf (bio_err, "-encrypt encrypt message\n"); BIO_printf (bio_err, "-decrypt decrypt encrypted message\n"); BIO_printf (bio_err, "-sign sign message\n"); BIO_printf (bio_err, "-verify verify signed message\n"); BIO_printf (bio_err, "-cmsout output CMS structure\n"); #ifndef OPENSSL_NO_DES BIO_printf (bio_err, "-des3 encrypt with triple DES\n"); BIO_printf (bio_err, "-des encrypt with DES\n"); #endif #ifndef OPENSSL_NO_SEED BIO_printf (bio_err, "-seed encrypt with SEED\n"); #endif #ifndef OPENSSL_NO_RC2 BIO_printf (bio_err, "-rc2-40 encrypt with RC2-40 (default)\n"); BIO_printf (bio_err, "-rc2-64 encrypt with RC2-64\n"); BIO_printf (bio_err, "-rc2-128 encrypt with RC2-128\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 #ifndef OPENSSL_NO_CAMELLIA BIO_printf (bio_err, "-camellia128, -camellia192, -camellia256\n"); BIO_printf (bio_err, " encrypt PEM output with cbc camellia\n"); #endif BIO_printf (bio_err, "-nointern don't search certificates in message for signer\n"); BIO_printf (bio_err, "-nosigs don't verify message signature\n"); BIO_printf (bio_err, "-noverify don't verify signers certificate\n"); BIO_printf (bio_err, "-nocerts don't include signers certificate when signing\n"); BIO_printf (bio_err, "-nodetach use opaque signing\n"); BIO_printf (bio_err, "-noattr don't include any signed attributes\n"); BIO_printf (bio_err, "-binary don't translate message to text\n"); BIO_printf (bio_err, "-certfile file other certificates file\n"); BIO_printf (bio_err, "-certsout file certificate output file\n"); BIO_printf (bio_err, "-signer file signer certificate file\n"); BIO_printf (bio_err, "-recip file recipient certificate file for decryption\n"); BIO_printf (bio_err, "-keyid use subject key identifier\n"); BIO_printf (bio_err, "-in file input file\n"); BIO_printf (bio_err, "-inform arg input format SMIME (default), PEM or DER\n"); BIO_printf (bio_err, "-inkey file input private key (if not signer or recipient)\n"); BIO_printf (bio_err, "-keyform arg input private key format (PEM or ENGINE)\n"); BIO_printf (bio_err, "-out file output file\n"); BIO_printf (bio_err, "-outform arg output format SMIME (default), PEM or DER\n"); BIO_printf (bio_err, "-content file supply or override content for detached signature\n"); BIO_printf (bio_err, "-to addr to address\n"); BIO_printf (bio_err, "-from ad from address\n"); BIO_printf (bio_err, "-subject s subject\n"); BIO_printf (bio_err, "-text include or delete text MIME headers\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, "-crl_check check revocation status of signer's certificate using CRLs\n"); BIO_printf (bio_err, "-crl_check_all check revocation status of signer's certificate chain using CRLs\n"); #ifndef OPENSSL_NO_ENGINE BIO_printf (bio_err, "-engine e use engine e, possibly a hardware device.\n"); #endif BIO_printf (bio_err, "-passin arg input file pass phrase source\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"); BIO_printf (bio_err, "cert.pem recipient certificate(s) for encryption\n"); goto end; } #ifndef OPENSSL_NO_ENGINE e = setup_engine(bio_err, engine, 0); #endif if (!app_passwd(bio_err, passargin, NULL, &passin, NULL)) { BIO_printf(bio_err, "Error getting password\n"); goto end; } if (need_rand) { 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)); } ret = 2; if (!(operation & SMIME_SIGNERS)) flags &= ~CMS_DETACHED; if (operation & SMIME_OP) { if (outformat == FORMAT_ASN1) outmode = "wb"; } else { if (flags & CMS_BINARY) outmode = "wb"; } if (operation & SMIME_IP) { if (informat == FORMAT_ASN1) inmode = "rb"; } else { if (flags & CMS_BINARY) inmode = "rb"; } if (operation == SMIME_ENCRYPT) { if (!cipher) { #ifndef OPENSSL_NO_DES cipher = EVP_des_ede3_cbc(); #else BIO_printf(bio_err, "No cipher selected\n"); goto end; #endif } if (secret_key && !secret_keyid) { BIO_printf(bio_err, "No secret key id\n"); goto end; } if (*args) encerts = sk_X509_new_null(); while (*args) { if (!(cert = load_cert(bio_err,*args,FORMAT_PEM, NULL, e, "recipient certificate file"))) goto end; sk_X509_push(encerts, cert); cert = NULL; args++; } } if (certfile) { if (!(other = load_certs(bio_err,certfile,FORMAT_PEM, NULL, e, "certificate file"))) { ERR_print_errors(bio_err); goto end; } } if (recipfile && (operation == SMIME_DECRYPT)) { if (!(recip = load_cert(bio_err,recipfile,FORMAT_PEM,NULL, e, "recipient certificate file"))) { ERR_print_errors(bio_err); goto end; } } if (operation == SMIME_SIGN_RECEIPT) { if (!(signer = load_cert(bio_err,signerfile,FORMAT_PEM,NULL, e, "receipt signer certificate file"))) { ERR_print_errors(bio_err); goto end; } } if (operation == SMIME_DECRYPT) { if (!keyfile) keyfile = recipfile; } else if ((operation == SMIME_SIGN) || (operation == SMIME_SIGN_RECEIPT)) { if (!keyfile) keyfile = signerfile; } else keyfile = NULL; if (keyfile) { key = load_key(bio_err, keyfile, keyform, 0, passin, e, "signing key file"); if (!key) goto end; } if (infile) { if (!(in = BIO_new_file(infile, inmode))) { BIO_printf (bio_err, "Can't open input file %s\n", infile); goto end; } } else in = BIO_new_fp(stdin, BIO_NOCLOSE); if (operation & SMIME_IP) { if (informat == FORMAT_SMIME) cms = SMIME_read_CMS(in, &indata); else if (informat == FORMAT_PEM) cms = PEM_read_bio_CMS(in, NULL, NULL, NULL); else if (informat == FORMAT_ASN1) cms = d2i_CMS_bio(in, NULL); else { BIO_printf(bio_err, "Bad input format for CMS file\n"); goto end; } if (!cms) { BIO_printf(bio_err, "Error reading S/MIME message\n"); goto end; } if (contfile) { BIO_free(indata); if (!(indata = BIO_new_file(contfile, "rb"))) { BIO_printf(bio_err, "Can't read content file %s\n", contfile); goto end; } } if (certsoutfile) { STACK_OF(X509) *allcerts; allcerts = CMS_get1_certs(cms); if (!save_certs(certsoutfile, allcerts)) { BIO_printf(bio_err, "Error writing certs to %s\n", certsoutfile); ret = 5; goto end; } sk_X509_pop_free(allcerts, X509_free); } } if (rctfile) { char *rctmode = (rctformat == FORMAT_ASN1) ? "rb" : "r"; if (!(rctin = BIO_new_file(rctfile, rctmode))) { BIO_printf (bio_err, "Can't open receipt file %s\n", rctfile); goto end; } if (rctformat == FORMAT_SMIME) rcms = SMIME_read_CMS(rctin, NULL); else if (rctformat == FORMAT_PEM) rcms = PEM_read_bio_CMS(rctin, NULL, NULL, NULL); else if (rctformat == FORMAT_ASN1) rcms = d2i_CMS_bio(rctin, NULL); else { BIO_printf(bio_err, "Bad input format for receipt\n"); goto end; } if (!rcms) { BIO_printf(bio_err, "Error reading receipt\n"); goto end; } } if (outfile) { if (!(out = BIO_new_file(outfile, outmode))) { BIO_printf (bio_err, "Can't open output file %s\n", outfile); goto end; } } else { out = BIO_new_fp(stdout, BIO_NOCLOSE); #ifdef OPENSSL_SYS_VMS { BIO *tmpbio = BIO_new(BIO_f_linebuffer()); out = BIO_push(tmpbio, out); } #endif } if ((operation == SMIME_VERIFY) || (operation == SMIME_VERIFY_RECEIPT)) { if (!(store = setup_verify(bio_err, CAfile, CApath))) goto end; X509_STORE_set_verify_cb(store, cms_cb); if (vpm) X509_STORE_set1_param(store, vpm); } ret = 3; if (operation == SMIME_DATA_CREATE) { cms = CMS_data_create(in, flags); } else if (operation == SMIME_DIGEST_CREATE) { cms = CMS_digest_create(in, sign_md, flags); } else if (operation == SMIME_COMPRESS) { cms = CMS_compress(in, -1, flags); } else if (operation == SMIME_ENCRYPT) { flags |= CMS_PARTIAL; cms = CMS_encrypt(encerts, in, cipher, flags); if (!cms) goto end; if (secret_key) { if (!CMS_add0_recipient_key(cms, NID_undef, secret_key, secret_keylen, secret_keyid, secret_keyidlen, NULL, NULL, NULL)) goto end; /* NULL these because call absorbs them */ secret_key = NULL; secret_keyid = NULL; } if (!(flags & CMS_STREAM)) { if (!CMS_final(cms, in, NULL, flags)) goto end; } } else if (operation == SMIME_ENCRYPTED_ENCRYPT) { cms = CMS_EncryptedData_encrypt(in, cipher, secret_key, secret_keylen, flags); } else if (operation == SMIME_SIGN_RECEIPT) { CMS_ContentInfo *srcms = NULL; STACK_OF(CMS_SignerInfo) *sis; CMS_SignerInfo *si; sis = CMS_get0_SignerInfos(cms); if (!sis) goto end; si = sk_CMS_SignerInfo_value(sis, 0); srcms = CMS_sign_receipt(si, signer, key, other, flags); if (!srcms) goto end; CMS_ContentInfo_free(cms); cms = srcms; } else if (operation & SMIME_SIGNERS) { int i; /* If detached data content we enable streaming if * S/MIME output format. */ if (operation == SMIME_SIGN) { if (flags & CMS_DETACHED) { if (outformat == FORMAT_SMIME) flags |= CMS_STREAM; } flags |= CMS_PARTIAL; cms = CMS_sign(NULL, NULL, other, in, flags); if (!cms) goto end; if (econtent_type) CMS_set1_eContentType(cms, econtent_type); if (rr_to) { rr = make_receipt_request(rr_to, rr_allorfirst, rr_from); if (!rr) { BIO_puts(bio_err, "Signed Receipt Request Creation Error\n"); goto end; } } } else flags |= CMS_REUSE_DIGEST; for (i = 0; i < sk_OPENSSL_STRING_num(sksigners); i++) { CMS_SignerInfo *si; signerfile = sk_OPENSSL_STRING_value(sksigners, i); keyfile = sk_OPENSSL_STRING_value(skkeys, i); signer = load_cert(bio_err, signerfile,FORMAT_PEM, NULL, e, "signer certificate"); if (!signer) goto end; key = load_key(bio_err, keyfile, keyform, 0, passin, e, "signing key file"); if (!key) goto end; si = CMS_add1_signer(cms, signer, key, sign_md, flags); if (!si) goto end; if (rr && !CMS_add1_ReceiptRequest(si, rr)) goto end; X509_free(signer); signer = NULL; EVP_PKEY_free(key); key = NULL; } /* If not streaming or resigning finalize structure */ if ((operation == SMIME_SIGN) && !(flags & CMS_STREAM)) { if (!CMS_final(cms, in, NULL, flags)) goto end; } } if (!cms) { BIO_printf(bio_err, "Error creating CMS structure\n"); goto end; } ret = 4; if (operation == SMIME_DECRYPT) { if (flags & CMS_DEBUG_DECRYPT) CMS_decrypt(cms, NULL, NULL, NULL, NULL, flags); if (secret_key) { if (!CMS_decrypt_set1_key(cms, secret_key, secret_keylen, secret_keyid, secret_keyidlen)) { BIO_puts(bio_err, "Error decrypting CMS using secret key\n"); goto end; } } if (key) { if (!CMS_decrypt_set1_pkey(cms, key, recip)) { BIO_puts(bio_err, "Error decrypting CMS using private key\n"); goto end; } } if (!CMS_decrypt(cms, NULL, NULL, indata, out, flags)) { BIO_printf(bio_err, "Error decrypting CMS structure\n"); goto end; } } else if (operation == SMIME_DATAOUT) { if (!CMS_data(cms, out, flags)) goto end; } else if (operation == SMIME_UNCOMPRESS) { if (!CMS_uncompress(cms, indata, out, flags)) goto end; } else if (operation == SMIME_DIGEST_VERIFY) { if (CMS_digest_verify(cms, indata, out, flags) > 0) BIO_printf(bio_err, "Verification successful\n"); else { BIO_printf(bio_err, "Verification failure\n"); goto end; } } else if (operation == SMIME_ENCRYPTED_DECRYPT) { if (!CMS_EncryptedData_decrypt(cms, secret_key, secret_keylen, indata, out, flags)) goto end; } else if (operation == SMIME_VERIFY) { if (CMS_verify(cms, other, store, indata, out, flags) > 0) BIO_printf(bio_err, "Verification successful\n"); else { BIO_printf(bio_err, "Verification failure\n"); if (verify_retcode) ret = verify_err + 32; goto end; } if (signerfile) { STACK_OF(X509) *signers; signers = CMS_get0_signers(cms); if (!save_certs(signerfile, signers)) { BIO_printf(bio_err, "Error writing signers to %s\n", signerfile); ret = 5; goto end; } sk_X509_free(signers); } if (rr_print) receipt_request_print(bio_err, cms); } else if (operation == SMIME_VERIFY_RECEIPT) { if (CMS_verify_receipt(rcms, cms, other, store, flags) > 0) BIO_printf(bio_err, "Verification successful\n"); else { BIO_printf(bio_err, "Verification failure\n"); goto end; } } else { if (noout) { if (print) CMS_ContentInfo_print_ctx(out, cms, 0, NULL); } else if (outformat == FORMAT_SMIME) { if (to) BIO_printf(out, "To: %s\n", to); if (from) BIO_printf(out, "From: %s\n", from); if (subject) BIO_printf(out, "Subject: %s\n", subject); if (operation == SMIME_RESIGN) ret = SMIME_write_CMS(out, cms, indata, flags); else ret = SMIME_write_CMS(out, cms, in, flags); } else if (outformat == FORMAT_PEM) ret = PEM_write_bio_CMS_stream(out, cms, in, flags); else if (outformat == FORMAT_ASN1) ret = i2d_CMS_bio_stream(out,cms, in, flags); else { BIO_printf(bio_err, "Bad output format for CMS file\n"); goto end; } if (ret <= 0) { ret = 6; goto end; } } ret = 0; end: if (ret) ERR_print_errors(bio_err); if (need_rand) app_RAND_write_file(NULL, bio_err); sk_X509_pop_free(encerts, X509_free); sk_X509_pop_free(other, X509_free); if (vpm) X509_VERIFY_PARAM_free(vpm); if (sksigners) sk_OPENSSL_STRING_free(sksigners); if (skkeys) sk_OPENSSL_STRING_free(skkeys); if (secret_key) OPENSSL_free(secret_key); if (secret_keyid) OPENSSL_free(secret_keyid); if (econtent_type) ASN1_OBJECT_free(econtent_type); if (rr) CMS_ReceiptRequest_free(rr); if (rr_to) sk_OPENSSL_STRING_free(rr_to); if (rr_from) sk_OPENSSL_STRING_free(rr_from); X509_STORE_free(store); X509_free(cert); X509_free(recip); X509_free(signer); EVP_PKEY_free(key); CMS_ContentInfo_free(cms); CMS_ContentInfo_free(rcms); BIO_free(rctin); BIO_free(in); BIO_free(indata); BIO_free_all(out); if (passin) OPENSSL_free(passin); return (ret); }
int x509_main(int argc, char **argv) { ASN1_INTEGER *sno = NULL; ASN1_OBJECT *objtmp = NULL; BIO *out = NULL; CONF *extconf = NULL; EVP_PKEY *Upkey = NULL, *CApkey = NULL, *fkey = NULL; STACK_OF(ASN1_OBJECT) *trust = NULL, *reject = NULL; STACK_OF(OPENSSL_STRING) *sigopts = NULL; X509 *x = NULL, *xca = NULL; X509_REQ *req = NULL, *rq = NULL; X509_STORE *ctx = NULL; const EVP_MD *digest = NULL; char *CAkeyfile = NULL, *CAserial = NULL, *fkeyfile = NULL, *alias = NULL; char *checkhost = NULL, *checkemail = NULL, *checkip = NULL, *exts = NULL; char *extsect = NULL, *extfile = NULL, *passin = NULL, *passinarg = NULL; char *infile = NULL, *outfile = NULL, *keyfile = NULL, *CAfile = NULL; char *prog; int x509req = 0, days = DEF_DAYS, modulus = 0, pubkey = 0, pprint = 0; int C = 0, CAformat = FORMAT_PEM, CAkeyformat = FORMAT_PEM; int fingerprint = 0, reqfile = 0, checkend = 0; int informat = FORMAT_PEM, outformat = FORMAT_PEM, keyformat = FORMAT_PEM; int next_serial = 0, subject_hash = 0, issuer_hash = 0, ocspid = 0; int noout = 0, sign_flag = 0, CA_flag = 0, CA_createserial = 0, email = 0; int ocsp_uri = 0, trustout = 0, clrtrust = 0, clrreject = 0, aliasout = 0; int ret = 1, i, num = 0, badsig = 0, clrext = 0, nocert = 0; int text = 0, serial = 0, subject = 0, issuer = 0, startdate = 0, ext = 0; int enddate = 0; time_t checkoffset = 0; unsigned long certflag = 0; int preserve_dates = 0; OPTION_CHOICE o; ENGINE *e = NULL; #ifndef OPENSSL_NO_MD5 int subject_hash_old = 0, issuer_hash_old = 0; #endif ctx = X509_STORE_new(); if (ctx == NULL) goto end; X509_STORE_set_verify_cb(ctx, callb); prog = opt_init(argc, argv, x509_options); while ((o = opt_next()) != OPT_EOF) { switch (o) { case OPT_EOF: case OPT_ERR: opthelp: BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); goto end; case OPT_HELP: opt_help(x509_options); ret = 0; goto end; case OPT_INFORM: if (!opt_format(opt_arg(), OPT_FMT_ANY, &informat)) goto opthelp; break; case OPT_IN: infile = opt_arg(); break; case OPT_OUTFORM: if (!opt_format(opt_arg(), OPT_FMT_ANY, &outformat)) goto opthelp; break; case OPT_KEYFORM: if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &keyformat)) goto opthelp; break; case OPT_CAFORM: if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &CAformat)) goto opthelp; break; case OPT_CAKEYFORM: if (!opt_format(opt_arg(), OPT_FMT_ANY, &CAkeyformat)) goto opthelp; break; case OPT_OUT: outfile = opt_arg(); break; case OPT_REQ: reqfile = 1; break; case OPT_SIGOPT: if (!sigopts) sigopts = sk_OPENSSL_STRING_new_null(); if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, opt_arg())) goto opthelp; break; case OPT_DAYS: if (preserve_dates) goto opthelp; days = atoi(opt_arg()); break; case OPT_PASSIN: passinarg = opt_arg(); break; case OPT_EXTFILE: extfile = opt_arg(); break; case OPT_R_CASES: if (!opt_rand(o)) goto end; break; case OPT_EXTENSIONS: extsect = opt_arg(); break; case OPT_SIGNKEY: keyfile = opt_arg(); sign_flag = ++num; break; case OPT_CA: CAfile = opt_arg(); CA_flag = ++num; break; case OPT_CAKEY: CAkeyfile = opt_arg(); break; case OPT_CASERIAL: CAserial = opt_arg(); break; case OPT_SET_SERIAL: if (sno != NULL) { BIO_printf(bio_err, "Serial number supplied twice\n"); goto opthelp; } if ((sno = s2i_ASN1_INTEGER(NULL, opt_arg())) == NULL) goto opthelp; break; case OPT_FORCE_PUBKEY: fkeyfile = opt_arg(); break; case OPT_ADDTRUST: if ((objtmp = OBJ_txt2obj(opt_arg(), 0)) == NULL) { BIO_printf(bio_err, "%s: Invalid trust object value %s\n", prog, opt_arg()); goto opthelp; } if (trust == NULL && (trust = sk_ASN1_OBJECT_new_null()) == NULL) goto end; sk_ASN1_OBJECT_push(trust, objtmp); objtmp = NULL; trustout = 1; break; case OPT_ADDREJECT: if ((objtmp = OBJ_txt2obj(opt_arg(), 0)) == NULL) { BIO_printf(bio_err, "%s: Invalid reject object value %s\n", prog, opt_arg()); goto opthelp; } if (reject == NULL && (reject = sk_ASN1_OBJECT_new_null()) == NULL) goto end; sk_ASN1_OBJECT_push(reject, objtmp); objtmp = NULL; trustout = 1; break; case OPT_SETALIAS: alias = opt_arg(); trustout = 1; break; case OPT_CERTOPT: if (!set_cert_ex(&certflag, opt_arg())) goto opthelp; break; case OPT_NAMEOPT: if (!set_nameopt(opt_arg())) goto opthelp; break; case OPT_ENGINE: e = setup_engine(opt_arg(), 0); break; case OPT_C: C = ++num; break; case OPT_EMAIL: email = ++num; break; case OPT_OCSP_URI: ocsp_uri = ++num; break; case OPT_SERIAL: serial = ++num; break; case OPT_NEXT_SERIAL: next_serial = ++num; break; case OPT_MODULUS: modulus = ++num; break; case OPT_PUBKEY: pubkey = ++num; break; case OPT_X509TOREQ: x509req = ++num; break; case OPT_TEXT: text = ++num; break; case OPT_SUBJECT: subject = ++num; break; case OPT_ISSUER: issuer = ++num; break; case OPT_FINGERPRINT: fingerprint = ++num; break; case OPT_HASH: subject_hash = ++num; break; case OPT_ISSUER_HASH: issuer_hash = ++num; break; case OPT_PURPOSE: pprint = ++num; break; case OPT_STARTDATE: startdate = ++num; break; case OPT_ENDDATE: enddate = ++num; break; case OPT_NOOUT: noout = ++num; break; case OPT_EXT: ext = ++num; exts = opt_arg(); break; case OPT_NOCERT: nocert = 1; break; case OPT_TRUSTOUT: trustout = 1; break; case OPT_CLRTRUST: clrtrust = ++num; break; case OPT_CLRREJECT: clrreject = ++num; break; case OPT_ALIAS: aliasout = ++num; break; case OPT_CACREATESERIAL: CA_createserial = ++num; break; case OPT_CLREXT: clrext = 1; break; case OPT_OCSPID: ocspid = ++num; break; case OPT_BADSIG: badsig = 1; break; #ifndef OPENSSL_NO_MD5 case OPT_SUBJECT_HASH_OLD: subject_hash_old = ++num; break; case OPT_ISSUER_HASH_OLD: issuer_hash_old = ++num; break; #else case OPT_SUBJECT_HASH_OLD: case OPT_ISSUER_HASH_OLD: break; #endif case OPT_DATES: startdate = ++num; enddate = ++num; break; case OPT_CHECKEND: checkend = 1; { intmax_t temp = 0; if (!opt_imax(opt_arg(), &temp)) goto opthelp; checkoffset = (time_t)temp; if ((intmax_t)checkoffset != temp) { BIO_printf(bio_err, "%s: checkend time out of range %s\n", prog, opt_arg()); goto opthelp; } } break; case OPT_CHECKHOST: checkhost = opt_arg(); break; case OPT_CHECKEMAIL: checkemail = opt_arg(); break; case OPT_CHECKIP: checkip = opt_arg(); break; case OPT_PRESERVE_DATES: if (days != DEF_DAYS) goto opthelp; preserve_dates = 1; break; case OPT_MD: if (!opt_md(opt_unknown(), &digest)) goto opthelp; } } argc = opt_num_rest(); argv = opt_rest(); if (argc != 0) { BIO_printf(bio_err, "%s: Unknown parameter %s\n", prog, argv[0]); goto opthelp; } if (!app_passwd(passinarg, NULL, &passin, NULL)) { BIO_printf(bio_err, "Error getting password\n"); goto end; } if (!X509_STORE_set_default_paths(ctx)) { ERR_print_errors(bio_err); goto end; } if (fkeyfile != NULL) { fkey = load_pubkey(fkeyfile, keyformat, 0, NULL, e, "Forced key"); if (fkey == NULL) goto end; } if ((CAkeyfile == NULL) && (CA_flag) && (CAformat == FORMAT_PEM)) { CAkeyfile = CAfile; } else if ((CA_flag) && (CAkeyfile == NULL)) { BIO_printf(bio_err, "need to specify a CAkey if using the CA command\n"); goto end; } if (extfile != NULL) { X509V3_CTX ctx2; if ((extconf = app_load_config(extfile)) == NULL) goto end; if (extsect == NULL) { extsect = NCONF_get_string(extconf, "default", "extensions"); if (extsect == NULL) { ERR_clear_error(); extsect = "default"; } } X509V3_set_ctx_test(&ctx2); X509V3_set_nconf(&ctx2, extconf); if (!X509V3_EXT_add_nconf(extconf, &ctx2, extsect, NULL)) { BIO_printf(bio_err, "Error Loading extension section %s\n", extsect); ERR_print_errors(bio_err); goto end; } } if (reqfile) { EVP_PKEY *pkey; BIO *in; if (!sign_flag && !CA_flag) { BIO_printf(bio_err, "We need a private key to sign with\n"); goto end; } in = bio_open_default(infile, 'r', informat); if (in == NULL) goto end; req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL); BIO_free(in); if (req == NULL) { ERR_print_errors(bio_err); goto end; } if ((pkey = X509_REQ_get0_pubkey(req)) == NULL) { BIO_printf(bio_err, "error unpacking public key\n"); goto end; } i = X509_REQ_verify(req, pkey); if (i < 0) { BIO_printf(bio_err, "Signature verification error\n"); ERR_print_errors(bio_err); goto end; } if (i == 0) { BIO_printf(bio_err, "Signature did not match the certificate request\n"); goto end; } else { BIO_printf(bio_err, "Signature ok\n"); } print_name(bio_err, "subject=", X509_REQ_get_subject_name(req), get_nameopt()); if ((x = X509_new()) == NULL) goto end; if (sno == NULL) { sno = ASN1_INTEGER_new(); if (sno == NULL || !rand_serial(NULL, sno)) goto end; if (!X509_set_serialNumber(x, sno)) goto end; ASN1_INTEGER_free(sno); sno = NULL; } else if (!X509_set_serialNumber(x, sno)) { goto end; } if (!X509_set_issuer_name(x, X509_REQ_get_subject_name(req))) goto end; if (!X509_set_subject_name(x, X509_REQ_get_subject_name(req))) goto end; if (!set_cert_times(x, NULL, NULL, days)) goto end; if (fkey != NULL) { X509_set_pubkey(x, fkey); } else { pkey = X509_REQ_get0_pubkey(req); X509_set_pubkey(x, pkey); } } else { x = load_cert(infile, informat, "Certificate"); } if (x == NULL) goto end; if (CA_flag) { xca = load_cert(CAfile, CAformat, "CA Certificate"); if (xca == NULL) goto end; } out = bio_open_default(outfile, 'w', outformat); if (out == NULL) goto end; if (!noout || text || next_serial) OBJ_create("2.99999.3", "SET.ex3", "SET x509v3 extension 3"); if (alias) X509_alias_set1(x, (unsigned char *)alias, -1); if (clrtrust) X509_trust_clear(x); if (clrreject) X509_reject_clear(x); if (trust != NULL) { for (i = 0; i < sk_ASN1_OBJECT_num(trust); i++) { objtmp = sk_ASN1_OBJECT_value(trust, i); X509_add1_trust_object(x, objtmp); } objtmp = NULL; } if (reject != NULL) { for (i = 0; i < sk_ASN1_OBJECT_num(reject); i++) { objtmp = sk_ASN1_OBJECT_value(reject, i); X509_add1_reject_object(x, objtmp); } objtmp = NULL; } if (badsig) { const ASN1_BIT_STRING *signature; X509_get0_signature(&signature, NULL, x); corrupt_signature(signature); } if (num) { for (i = 1; i <= num; i++) { if (issuer == i) { print_name(out, "issuer=", X509_get_issuer_name(x), get_nameopt()); } else if (subject == i) { print_name(out, "subject=", X509_get_subject_name(x), get_nameopt()); } else if (serial == i) { BIO_printf(out, "serial="); i2a_ASN1_INTEGER(out, X509_get_serialNumber(x)); BIO_printf(out, "\n"); } else if (next_serial == i) { ASN1_INTEGER *ser = X509_get_serialNumber(x); BIGNUM *bnser = ASN1_INTEGER_to_BN(ser, NULL); if (!bnser) goto end; if (!BN_add_word(bnser, 1)) goto end; ser = BN_to_ASN1_INTEGER(bnser, NULL); if (!ser) goto end; BN_free(bnser); i2a_ASN1_INTEGER(out, ser); ASN1_INTEGER_free(ser); BIO_puts(out, "\n"); } else if ((email == i) || (ocsp_uri == i)) { int j; STACK_OF(OPENSSL_STRING) *emlst; if (email == i) emlst = X509_get1_email(x); else emlst = X509_get1_ocsp(x); for (j = 0; j < sk_OPENSSL_STRING_num(emlst); j++) BIO_printf(out, "%s\n", sk_OPENSSL_STRING_value(emlst, j)); X509_email_free(emlst); } else if (aliasout == i) { unsigned char *alstr; alstr = X509_alias_get0(x, NULL); if (alstr) BIO_printf(out, "%s\n", alstr); else BIO_puts(out, "<No Alias>\n"); } else if (subject_hash == i) { BIO_printf(out, "%08lx\n", X509_subject_name_hash(x)); } #ifndef OPENSSL_NO_MD5 else if (subject_hash_old == i) { BIO_printf(out, "%08lx\n", X509_subject_name_hash_old(x)); } #endif else if (issuer_hash == i) { BIO_printf(out, "%08lx\n", X509_issuer_name_hash(x)); } #ifndef OPENSSL_NO_MD5 else if (issuer_hash_old == i) { BIO_printf(out, "%08lx\n", X509_issuer_name_hash_old(x)); } #endif else if (pprint == i) { X509_PURPOSE *ptmp; int j; BIO_printf(out, "Certificate purposes:\n"); for (j = 0; j < X509_PURPOSE_get_count(); j++) { ptmp = X509_PURPOSE_get0(j); purpose_print(out, x, ptmp); } } else if (modulus == i) { EVP_PKEY *pkey; pkey = X509_get0_pubkey(x); if (pkey == NULL) { BIO_printf(bio_err, "Modulus=unavailable\n"); ERR_print_errors(bio_err); goto end; } BIO_printf(out, "Modulus="); #ifndef OPENSSL_NO_RSA if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA) { const BIGNUM *n; RSA_get0_key(EVP_PKEY_get0_RSA(pkey), &n, NULL, NULL); BN_print(out, n); } else #endif #ifndef OPENSSL_NO_DSA if (EVP_PKEY_id(pkey) == EVP_PKEY_DSA) { const BIGNUM *dsapub = NULL; DSA_get0_key(EVP_PKEY_get0_DSA(pkey), &dsapub, NULL); BN_print(out, dsapub); } else #endif { BIO_printf(out, "Wrong Algorithm type"); } BIO_printf(out, "\n"); } else if (pubkey == i) { EVP_PKEY *pkey; pkey = X509_get0_pubkey(x); if (pkey == NULL) { BIO_printf(bio_err, "Error getting public key\n"); ERR_print_errors(bio_err); goto end; } PEM_write_bio_PUBKEY(out, pkey); } else if (C == i) { unsigned char *d; char *m; int len; print_name(out, "/*\n" " * Subject: ", X509_get_subject_name(x), get_nameopt()); print_name(out, " * Issuer: ", X509_get_issuer_name(x), get_nameopt()); BIO_puts(out, " */\n"); len = i2d_X509(x, NULL); m = app_malloc(len, "x509 name buffer"); d = (unsigned char *)m; len = i2d_X509_NAME(X509_get_subject_name(x), &d); print_array(out, "the_subject_name", len, (unsigned char *)m); d = (unsigned char *)m; len = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(x), &d); print_array(out, "the_public_key", len, (unsigned char *)m); d = (unsigned char *)m; len = i2d_X509(x, &d); print_array(out, "the_certificate", len, (unsigned char *)m); OPENSSL_free(m); } else if (text == i) { X509_print_ex(out, x, get_nameopt(), certflag); } else if (startdate == i) { BIO_puts(out, "notBefore="); ASN1_TIME_print(out, X509_get0_notBefore(x)); BIO_puts(out, "\n"); } else if (enddate == i) { BIO_puts(out, "notAfter="); ASN1_TIME_print(out, X509_get0_notAfter(x)); BIO_puts(out, "\n"); } else if (fingerprint == i) { int j; unsigned int n; unsigned char md[EVP_MAX_MD_SIZE]; const EVP_MD *fdig = digest; if (fdig == NULL) fdig = EVP_sha1(); if (!X509_digest(x, fdig, md, &n)) { BIO_printf(bio_err, "out of memory\n"); goto end; } BIO_printf(out, "%s Fingerprint=", OBJ_nid2sn(EVP_MD_type(fdig))); for (j = 0; j < (int)n; j++) { BIO_printf(out, "%02X%c", md[j], (j + 1 == (int)n) ? '\n' : ':'); } } /* should be in the library */ else if ((sign_flag == i) && (x509req == 0)) { BIO_printf(bio_err, "Getting Private key\n"); if (Upkey == NULL) { Upkey = load_key(keyfile, keyformat, 0, passin, e, "Private key"); if (Upkey == NULL) goto end; } if (!sign(x, Upkey, days, clrext, digest, extconf, extsect, preserve_dates)) goto end; } else if (CA_flag == i) { BIO_printf(bio_err, "Getting CA Private Key\n"); if (CAkeyfile != NULL) { CApkey = load_key(CAkeyfile, CAkeyformat, 0, passin, e, "CA Private Key"); if (CApkey == NULL) goto end; } if (!x509_certify(ctx, CAfile, digest, x, xca, CApkey, sigopts, CAserial, CA_createserial, days, clrext, extconf, extsect, sno, reqfile, preserve_dates)) goto end; } else if (x509req == i) { EVP_PKEY *pk; BIO_printf(bio_err, "Getting request Private Key\n"); if (keyfile == NULL) { BIO_printf(bio_err, "no request key file specified\n"); goto end; } else { pk = load_key(keyfile, keyformat, 0, passin, e, "request key"); if (pk == NULL) goto end; } BIO_printf(bio_err, "Generating certificate request\n"); rq = X509_to_X509_REQ(x, pk, digest); EVP_PKEY_free(pk); if (rq == NULL) { ERR_print_errors(bio_err); goto end; } if (!noout) { X509_REQ_print_ex(out, rq, get_nameopt(), X509_FLAG_COMPAT); PEM_write_bio_X509_REQ(out, rq); } noout = 1; } else if (ocspid == i) { X509_ocspid_print(out, x); } else if (ext == i) { print_x509v3_exts(out, x, exts); } } } if (checkend) { time_t tcheck = time(NULL) + checkoffset; if (X509_cmp_time(X509_get0_notAfter(x), &tcheck) < 0) { BIO_printf(out, "Certificate will expire\n"); ret = 1; } else { BIO_printf(out, "Certificate will not expire\n"); ret = 0; } goto end; } print_cert_checks(out, x, checkhost, checkemail, checkip); if (noout || nocert) { ret = 0; goto end; } if (outformat == FORMAT_ASN1) { i = i2d_X509_bio(out, x); } else if (outformat == FORMAT_PEM) { if (trustout) i = PEM_write_bio_X509_AUX(out, x); else i = PEM_write_bio_X509(out, x); } else { BIO_printf(bio_err, "bad output format specified for outfile\n"); goto end; } if (!i) { BIO_printf(bio_err, "unable to write certificate\n"); ERR_print_errors(bio_err); goto end; } ret = 0; end: NCONF_free(extconf); BIO_free_all(out); X509_STORE_free(ctx); X509_REQ_free(req); X509_free(x); X509_free(xca); EVP_PKEY_free(Upkey); EVP_PKEY_free(CApkey); EVP_PKEY_free(fkey); sk_OPENSSL_STRING_free(sigopts); X509_REQ_free(rq); ASN1_INTEGER_free(sno); sk_ASN1_OBJECT_pop_free(trust, ASN1_OBJECT_free); sk_ASN1_OBJECT_pop_free(reject, ASN1_OBJECT_free); ASN1_OBJECT_free(objtmp); release_engine(e); OPENSSL_free(passin); return ret; }
/* returning zero (0) means success, everything else is treated as "failure" with no care exactly what the failure was */ int Curl_input_negotiate(struct connectdata *conn, bool proxy, const char *header) { struct negotiatedata *neg_ctx = proxy?&conn->data->state.proxyneg: &conn->data->state.negotiate; OM_uint32 major_status, minor_status, minor_status2; gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER; gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER; int ret; size_t len, rawlen; bool gss; const char* protocol; while(*header && ISSPACE(*header)) header++; if(checkprefix("GSS-Negotiate", header)) { protocol = "GSS-Negotiate"; gss = TRUE; } else if(checkprefix("Negotiate", header)) { protocol = "Negotiate"; gss = FALSE; } else return -1; if(neg_ctx->context) { if(neg_ctx->gss != gss) { return -1; } } else { neg_ctx->protocol = protocol; neg_ctx->gss = gss; } if(neg_ctx->context && neg_ctx->status == GSS_S_COMPLETE) { /* We finished successfully our part of authentication, but server * rejected it (since we're again here). Exit with an error since we * can't invent anything better */ Curl_cleanup_negotiate(conn->data); return -1; } if(neg_ctx->server_name == NULL && (ret = get_gss_name(conn, proxy, &neg_ctx->server_name))) return ret; header += strlen(neg_ctx->protocol); while(*header && ISSPACE(*header)) header++; len = strlen(header); if(len > 0) { rawlen = Curl_base64_decode(header, (unsigned char **)&input_token.value); if(rawlen == 0) return -1; input_token.length = rawlen; #ifdef HAVE_SPNEGO /* Handle SPNEGO */ if(checkprefix("Negotiate", header)) { ASN1_OBJECT * object = NULL; int rc = 1; unsigned char * spnegoToken = NULL; size_t spnegoTokenLength = 0; unsigned char * mechToken = NULL; size_t mechTokenLength = 0; if(input_token.value == NULL) return CURLE_OUT_OF_MEMORY; spnegoToken = malloc(input_token.length); if(spnegoToken == NULL) return CURLE_OUT_OF_MEMORY; spnegoTokenLength = input_token.length; object = OBJ_txt2obj ("1.2.840.113554.1.2.2", 1); if(!parseSpnegoTargetToken(spnegoToken, spnegoTokenLength, NULL, NULL, &mechToken, &mechTokenLength, NULL, NULL)) { free(spnegoToken); spnegoToken = NULL; infof(conn->data, "Parse SPNEGO Target Token failed\n"); } else { free(input_token.value); input_token.value = malloc(mechTokenLength); if(input_token.value == NULL) return CURLE_OUT_OF_MEMORY; memcpy(input_token.value, mechToken,mechTokenLength); input_token.length = mechTokenLength; free(mechToken); mechToken = NULL; infof(conn->data, "Parse SPNEGO Target Token succeeded\n"); } } #endif } major_status = Curl_gss_init_sec_context(&minor_status, &neg_ctx->context, neg_ctx->server_name, GSS_C_NO_CHANNEL_BINDINGS, &input_token, &output_token, NULL); if(input_token.length > 0) gss_release_buffer(&minor_status2, &input_token); neg_ctx->status = major_status; if(GSS_ERROR(major_status)) { /* Curl_cleanup_negotiate(conn->data) ??? */ log_gss_error(conn, minor_status, "gss_init_sec_context() failed: "); return -1; } if(output_token.length == 0) { return -1; } neg_ctx->output_token = output_token; /* conn->bits.close = FALSE; */ return 0; }
int opt_verify(int opt, X509_VERIFY_PARAM *vpm) { unsigned long ul; int i; ASN1_OBJECT *otmp; X509_PURPOSE *xptmp; const X509_VERIFY_PARAM *vtmp; assert(vpm != NULL); assert(opt > OPT_V__FIRST); assert(opt < OPT_V__LAST); switch ((enum range)opt) { case OPT_V__FIRST: case OPT_V__LAST: return 0; case OPT_V_POLICY: otmp = OBJ_txt2obj(opt_arg(), 0); if (otmp == NULL) { BIO_printf(bio_err, "%s: Invalid Policy %s\n", prog, opt_arg()); return 0; } X509_VERIFY_PARAM_add0_policy(vpm, otmp); break; case OPT_V_PURPOSE: i = X509_PURPOSE_get_by_sname(opt_arg()); if (i < 0) { BIO_printf(bio_err, "%s: Invalid purpose %s\n", prog, opt_arg()); return 0; } xptmp = X509_PURPOSE_get0(i); i = X509_PURPOSE_get_id(xptmp); X509_VERIFY_PARAM_set_purpose(vpm, i); break; case OPT_V_VERIFY_NAME: vtmp = X509_VERIFY_PARAM_lookup(opt_arg()); if (vtmp == NULL) { BIO_printf(bio_err, "%s: Invalid verify name %s\n", prog, opt_arg()); return 0; } X509_VERIFY_PARAM_set1(vpm, vtmp); break; case OPT_V_VERIFY_DEPTH: i = atoi(opt_arg()); if (i >= 0) X509_VERIFY_PARAM_set_depth(vpm, i); break; case OPT_V_ATTIME: opt_ulong(opt_arg(), &ul); if (ul) X509_VERIFY_PARAM_set_time(vpm, (time_t)ul); break; case OPT_V_VERIFY_HOSTNAME: if (!X509_VERIFY_PARAM_set1_host(vpm, opt_arg(), 0)) return 0; break; case OPT_V_VERIFY_EMAIL: if (!X509_VERIFY_PARAM_set1_email(vpm, opt_arg(), 0)) return 0; break; case OPT_V_VERIFY_IP: if (!X509_VERIFY_PARAM_set1_ip_asc(vpm, opt_arg())) return 0; break; case OPT_V_IGNORE_CRITICAL: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_IGNORE_CRITICAL); break; case OPT_V_ISSUER_CHECKS: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_CB_ISSUER_CHECK); break; case OPT_V_CRL_CHECK: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_CRL_CHECK); break; case OPT_V_CRL_CHECK_ALL: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL); break; case OPT_V_POLICY_CHECK: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_POLICY_CHECK); break; case OPT_V_EXPLICIT_POLICY: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_EXPLICIT_POLICY); break; case OPT_V_INHIBIT_ANY: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_INHIBIT_ANY); break; case OPT_V_INHIBIT_MAP: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_INHIBIT_MAP); break; case OPT_V_X509_STRICT: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_X509_STRICT); break; case OPT_V_EXTENDED_CRL: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_EXTENDED_CRL_SUPPORT); break; case OPT_V_USE_DELTAS: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_USE_DELTAS); break; case OPT_V_POLICY_PRINT: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_NOTIFY_POLICY); break; case OPT_V_CHECK_SS_SIG: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_CHECK_SS_SIGNATURE); break; case OPT_V_TRUSTED_FIRST: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_TRUSTED_FIRST); break; case OPT_V_SUITEB_128_ONLY: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_SUITEB_128_LOS_ONLY); break; case OPT_V_SUITEB_128: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_SUITEB_128_LOS); break; case OPT_V_SUITEB_192: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_SUITEB_192_LOS); break; case OPT_V_PARTIAL_CHAIN: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_PARTIAL_CHAIN); break; case OPT_V_NO_ALT_CHAINS: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_NO_ALT_CHAINS); } return 1; }
int test(char *URL) { CURLM* multi; sslctxparm p; CURLMcode res; int running; char done = FALSE; int i = 0; CURLMsg *msg; struct timeval ml_start; struct timeval mp_start; char ml_timedout = FALSE; char mp_timedout = FALSE; if(arg2) { portnum = atoi(arg2); } if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { fprintf(stderr, "curl_global_init() failed\n"); return TEST_ERR_MAJOR_BAD; } if ((p.curl = curl_easy_init()) == NULL) { fprintf(stderr, "curl_easy_init() failed\n"); curl_global_cleanup(); return TEST_ERR_MAJOR_BAD; } p.accessinfoURL = (unsigned char *) strdup(URL); p.accesstype = OBJ_obj2nid(OBJ_txt2obj("AD_DVCS",0)) ; curl_easy_setopt(p.curl, CURLOPT_URL, p.accessinfoURL); curl_easy_setopt(p.curl, CURLOPT_SSL_CTX_FUNCTION, sslctxfun) ; curl_easy_setopt(p.curl, CURLOPT_SSL_CTX_DATA, &p); curl_easy_setopt(p.curl, CURLOPT_SSL_VERIFYPEER, FALSE); curl_easy_setopt(p.curl, CURLOPT_SSL_VERIFYHOST, 1); if ((multi = curl_multi_init()) == NULL) { fprintf(stderr, "curl_multi_init() failed\n"); curl_easy_cleanup(p.curl); curl_global_cleanup(); return TEST_ERR_MAJOR_BAD; } if ((res = curl_multi_add_handle(multi, p.curl)) != CURLM_OK) { fprintf(stderr, "curl_multi_add_handle() failed, " "with code %d\n", res); curl_multi_cleanup(multi); curl_easy_cleanup(p.curl); curl_global_cleanup(); return TEST_ERR_MAJOR_BAD; } fprintf(stderr, "Going to perform %s\n", (char *)p.accessinfoURL); ml_timedout = FALSE; ml_start = tutil_tvnow(); while (!done) { fd_set rd, wr, exc; int max_fd; struct timeval interval; interval.tv_sec = 1; interval.tv_usec = 0; if (tutil_tvdiff(tutil_tvnow(), ml_start) > MAIN_LOOP_HANG_TIMEOUT) { ml_timedout = TRUE; break; } mp_timedout = FALSE; mp_start = tutil_tvnow(); while (res == CURLM_CALL_MULTI_PERFORM) { res = curl_multi_perform(multi, &running); if (tutil_tvdiff(tutil_tvnow(), mp_start) > MULTI_PERFORM_HANG_TIMEOUT) { mp_timedout = TRUE; break; } fprintf(stderr, "running=%d res=%d\n",running,res); if (running <= 0) { done = TRUE; break; } } if (mp_timedout || done) break; if (res != CURLM_OK) { fprintf(stderr, "not okay???\n"); i = 80; break; } FD_ZERO(&rd); FD_ZERO(&wr); FD_ZERO(&exc); max_fd = 0; if (curl_multi_fdset(multi, &rd, &wr, &exc, &max_fd) != CURLM_OK) { fprintf(stderr, "unexpected failured of fdset.\n"); i = 89; break; } if (select_test(max_fd+1, &rd, &wr, &exc, &interval) == -1) { fprintf(stderr, "bad select??\n"); i =95; break; } res = CURLM_CALL_MULTI_PERFORM; } if (ml_timedout || mp_timedout) { if (ml_timedout) fprintf(stderr, "ml_timedout\n"); if (mp_timedout) fprintf(stderr, "mp_timedout\n"); fprintf(stderr, "ABORTING TEST, since it seems " "that it would have run forever.\n"); i = TEST_ERR_RUNS_FOREVER; } else { msg = curl_multi_info_read(multi, &running); /* this should now contain a result code from the easy handle, get it */ if(msg) i = msg->data.result; fprintf(stderr, "all done\n"); } curl_multi_remove_handle(multi, p.curl); curl_easy_cleanup(p.curl); curl_multi_cleanup(multi); curl_global_cleanup(); free(p.accessinfoURL); return i; }
/* Helper function to trace the signing cert to a trusted CA root * in the OpenSSL Trust Store. */ static int checkCertOpenSSL(const GTPublicationsFile *publications_file) { int res = GT_UNKNOWN_ERROR; unsigned char *cert_der = NULL; size_t cert_der_len; unsigned char *cert_tmp; X509 *cert = NULL; X509_STORE_CTX *store_ctx = NULL; X509_NAME *subj = NULL; ASN1_OBJECT *oid = NULL; char tmp_name[256]; int rc; res = GTPublicationsFile_getSigningCert(publications_file, &cert_der, &cert_der_len); if (res != GT_OK) { goto cleanup; } /* Note that d2i_X509() spoils the pointer to the buffer, use a temporary copy. */ cert_tmp = cert_der; cert = d2i_X509(NULL, (const unsigned char **) &cert_tmp, cert_der_len); if (cert == NULL) { res = GT_NOT_VALID_PUBLICATION; goto cleanup; } #ifdef MAGIC_EMAIL subj = X509_get_subject_name(cert); if (subj == NULL) { res = GT_CRYPTO_FAILURE; goto cleanup; } oid = OBJ_txt2obj("1.2.840.113549.1.9.1", 1); if (oid == NULL) { res = GT_OUT_OF_MEMORY; goto cleanup; } rc = X509_NAME_get_text_by_OBJ(subj, oid, tmp_name, sizeof(tmp_name)); if (rc < 0) { res = GT_INVALID_SIGNATURE; goto cleanup; } if (strcmp(tmp_name, MAGIC_EMAIL) != 0) { res = GT_INVALID_SIGNATURE; goto cleanup; } #endif store_ctx = X509_STORE_CTX_new(); if (store_ctx == NULL) { res = GT_OUT_OF_MEMORY; goto cleanup; } /* The truststore is not initialized by default. */ if (GT_truststore == NULL) { res = GTTruststore_init(1); if (res != GT_OK) goto cleanup; } if (!X509_STORE_CTX_init(store_ctx, GT_truststore, cert, publications_file->signature->d.sign->cert)) { res = GT_OUT_OF_MEMORY; goto cleanup; } rc = X509_verify_cert(store_ctx); if (rc < 0) { res = GT_CRYPTO_FAILURE; goto cleanup; } if (rc != 1) { res = GT_CERT_NOT_TRUSTED; goto cleanup; } res = GT_OK; cleanup: GT_free(cert_der); /* Do not free subj, it points into cert. */ ASN1_OBJECT_free(oid); if (cert != NULL) { X509_free(cert); } if (store_ctx != NULL) { X509_STORE_CTX_free(store_ctx); } return res; }
int opt_verify(int opt, X509_VERIFY_PARAM *vpm) { int i; ossl_intmax_t t = 0; ASN1_OBJECT *otmp; X509_PURPOSE *xptmp; const X509_VERIFY_PARAM *vtmp; assert(vpm != NULL); assert(opt > OPT_V__FIRST); assert(opt < OPT_V__LAST); switch ((enum range)opt) { case OPT_V__FIRST: case OPT_V__LAST: return 0; case OPT_V_POLICY: otmp = OBJ_txt2obj(opt_arg(), 0); if (otmp == NULL) { BIO_printf(bio_err, "%s: Invalid Policy %s\n", prog, opt_arg()); return 0; } X509_VERIFY_PARAM_add0_policy(vpm, otmp); break; case OPT_V_PURPOSE: /* purpose name -> purpose index */ i = X509_PURPOSE_get_by_sname(opt_arg()); if (i < 0) { BIO_printf(bio_err, "%s: Invalid purpose %s\n", prog, opt_arg()); return 0; } /* purpose index -> purpose object */ xptmp = X509_PURPOSE_get0(i); /* purpose object -> purpose value */ i = X509_PURPOSE_get_id(xptmp); if (!X509_VERIFY_PARAM_set_purpose(vpm, i)) { BIO_printf(bio_err, "%s: Internal error setting purpose %s\n", prog, opt_arg()); return 0; } break; case OPT_V_VERIFY_NAME: vtmp = X509_VERIFY_PARAM_lookup(opt_arg()); if (vtmp == NULL) { BIO_printf(bio_err, "%s: Invalid verify name %s\n", prog, opt_arg()); return 0; } X509_VERIFY_PARAM_set1(vpm, vtmp); break; case OPT_V_VERIFY_DEPTH: i = atoi(opt_arg()); if (i >= 0) X509_VERIFY_PARAM_set_depth(vpm, i); break; case OPT_V_VERIFY_AUTH_LEVEL: i = atoi(opt_arg()); if (i >= 0) X509_VERIFY_PARAM_set_auth_level(vpm, i); break; case OPT_V_ATTIME: if (!opt_imax(opt_arg(), &t)) return 0; if (t != (time_t)t) { BIO_printf(bio_err, "%s: epoch time out of range %s\n", prog, opt_arg()); return 0; } X509_VERIFY_PARAM_set_time(vpm, (time_t)t); break; case OPT_V_VERIFY_HOSTNAME: if (!X509_VERIFY_PARAM_set1_host(vpm, opt_arg(), 0)) return 0; break; case OPT_V_VERIFY_EMAIL: if (!X509_VERIFY_PARAM_set1_email(vpm, opt_arg(), 0)) return 0; break; case OPT_V_VERIFY_IP: if (!X509_VERIFY_PARAM_set1_ip_asc(vpm, opt_arg())) return 0; break; case OPT_V_IGNORE_CRITICAL: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_IGNORE_CRITICAL); break; case OPT_V_ISSUER_CHECKS: /* NOP, deprecated */ break; case OPT_V_CRL_CHECK: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_CRL_CHECK); break; case OPT_V_CRL_CHECK_ALL: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL); break; case OPT_V_POLICY_CHECK: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_POLICY_CHECK); break; case OPT_V_EXPLICIT_POLICY: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_EXPLICIT_POLICY); break; case OPT_V_INHIBIT_ANY: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_INHIBIT_ANY); break; case OPT_V_INHIBIT_MAP: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_INHIBIT_MAP); break; case OPT_V_X509_STRICT: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_X509_STRICT); break; case OPT_V_EXTENDED_CRL: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_EXTENDED_CRL_SUPPORT); break; case OPT_V_USE_DELTAS: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_USE_DELTAS); break; case OPT_V_POLICY_PRINT: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_NOTIFY_POLICY); break; case OPT_V_CHECK_SS_SIG: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_CHECK_SS_SIGNATURE); break; case OPT_V_TRUSTED_FIRST: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_TRUSTED_FIRST); break; case OPT_V_SUITEB_128_ONLY: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_SUITEB_128_LOS_ONLY); break; case OPT_V_SUITEB_128: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_SUITEB_128_LOS); break; case OPT_V_SUITEB_192: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_SUITEB_192_LOS); break; case OPT_V_PARTIAL_CHAIN: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_PARTIAL_CHAIN); break; case OPT_V_NO_ALT_CHAINS: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_NO_ALT_CHAINS); break; case OPT_V_NO_CHECK_TIME: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_NO_CHECK_TIME); break; } return 1; }
/** Determines if the specified EKUs are present in a signing certificate. @param[in] SignerCert The certificate to check. @param[in] RequiredEKUs The EKUs to look for. @param[in] RequiredEKUsSize The number of EKUs @param[in] RequireAllPresent If TRUE, then all the specified EKUs must be present in the certificate. @retval EFI_SUCCESS We successfully identified the signing type. @retval EFI_INVALID_PARAMETER A parameter was invalid. @retval EFI_NOT_FOUND One or more EKU's were not found in the signature. **/ EFI_STATUS CheckEKUs( IN CONST X509 *SignerCert, IN CONST CHAR8 *RequiredEKUs[], IN CONST UINT32 RequiredEKUsSize, IN BOOLEAN RequireAllPresent ) { EFI_STATUS Status; ASN1_OBJECT *Asn1ToFind; UINT32 NumEkusFound; UINT32 Index; Status = EFI_SUCCESS; Asn1ToFind = NULL; NumEkusFound = 0; if (SignerCert == NULL || RequiredEKUs == NULL || RequiredEKUsSize == 0) { Status = EFI_INVALID_PARAMETER; goto Exit; } for (Index = 0; Index < RequiredEKUsSize; Index++) { // // Finding required EKU in cert. // if (Asn1ToFind) { ASN1_OBJECT_free(Asn1ToFind); Asn1ToFind = NULL; } Asn1ToFind = OBJ_txt2obj (RequiredEKUs[Index], 0); if (!Asn1ToFind) { // // Fail to convert required EKU to ASN1. // Status = EFI_INVALID_PARAMETER; goto Exit; } Status = IsEkuInCertificate (SignerCert, Asn1ToFind); if (Status == EFI_SUCCESS) { NumEkusFound++; if (!RequireAllPresent) { // // Found at least one, so we are done. // goto Exit; } } else { // // Fail to find Eku in cert break; } } Exit: if (Asn1ToFind) { ASN1_OBJECT_free(Asn1ToFind); } if (RequireAllPresent && NumEkusFound == RequiredEKUsSize) { // // Found all required EKUs in certificate. // Status = EFI_SUCCESS; } return Status; }