/* * GetConfigPtr is a public C-level function for getting OpenSSL CONF struct * from an OpenSSL::Config(eConfig) instance. We decided to implement * OpenSSL::Config in Ruby level but we need to pass native CONF struct for * some OpenSSL features such as X509V3_EXT_*. */ CONF * GetConfigPtr(VALUE obj) { CONF *conf; VALUE str; BIO *bio; long eline = -1; OSSL_Check_Kind(obj, cConfig); str = rb_funcall(obj, rb_intern("to_s"), 0); bio = ossl_obj2bio(str); conf = NCONF_new(NULL); if(!conf) { BIO_free(bio); ossl_raise(eConfigError, NULL); } if(!NCONF_load_bio(conf, bio, &eline)) { BIO_free(bio); NCONF_free(conf); if (eline <= 0) ossl_raise(eConfigError, "wrong config format"); else ossl_raise(eConfigError, "error in line %d", eline); ossl_raise(eConfigError, NULL); } BIO_free(bio); return conf; }
LHASH *CONF_load_bio(LHASH *conf, BIO *bp,long *eline) { CONF ctmp; int ret; CONF_set_nconf(&ctmp, conf); ret = NCONF_load_bio(&ctmp, bp, eline); if (ret) return ctmp.data; return NULL; }
int FuzzerTestOneInput(const uint8_t *buf, size_t len) { CONF *conf = NCONF_new(NULL); BIO *in = BIO_new(BIO_s_mem()); long eline; OPENSSL_assert((size_t)BIO_write(in, buf, len) == len); NCONF_load_bio(conf, in, &eline); //NCONF_dump_fp(conf, stdout); NCONF_free(conf); BIO_free(in); return 0; }
int NCONF_load_fp(CONF *conf, FILE *fp,long *eline) { BIO *btmp; int ret; if(!(btmp = BIO_new_fp(fp, BIO_NOCLOSE))) { CONFerr(CONF_F_NCONF_LOAD_FP,ERR_R_BUF_LIB); return 0; } ret = NCONF_load_bio(conf, btmp, eline); BIO_free(btmp); return ret; }
/* * Private */ static CONF * parse_config(VALUE str, CONF *dst) { CONF *conf; BIO *bio; long eline = -1; bio = ossl_obj2bio(str); conf = dst ? dst : NCONF_new(NULL); if(!conf){ BIO_free(bio); ossl_raise(eConfigError, NULL); } if(!NCONF_load_bio(conf, bio, &eline)){ BIO_free(bio); if(!dst) NCONF_free(conf); if (eline <= 0) ossl_raise(eConfigError, "wrong config format"); else ossl_raise(eConfigError, "error in line %d", eline); ossl_raise(eConfigError, NULL); } BIO_free(bio); return conf; }
int MAIN(int argc, char **argv) { ENGINE *e = NULL; int i,badops=0, ret = 1; BIO *in = NULL,*out = NULL; int verify=0,noout=0,pubkey=0; char *infile = NULL,*outfile = NULL,*prog; char *passargin = NULL, *passin = NULL; const char *spkac = "SPKAC", *spksect = "default"; char *spkstr = NULL; char *challenge = NULL, *keyfile = NULL; CONF *conf = NULL; NETSCAPE_SPKI *spki = NULL; EVP_PKEY *pkey = NULL; #ifndef OPENSSL_NO_ENGINE char *engine=NULL; #endif apps_startup(); if (!bio_err) bio_err = BIO_new_fp(OPENSSL_TYPE__FILE_STDERR, BIO_NOCLOSE); if (!load_config(bio_err, NULL)) goto end; prog=argv[0]; argc--; argv++; while (argc >= 1) { if (TINYCLR_SSL_STRCMP(*argv,"-in") == 0) { if (--argc < 1) goto bad; infile= *(++argv); } else if (TINYCLR_SSL_STRCMP(*argv,"-out") == 0) { if (--argc < 1) goto bad; outfile= *(++argv); } else if (TINYCLR_SSL_STRCMP(*argv,"-passin") == 0) { if (--argc < 1) goto bad; passargin= *(++argv); } else if (TINYCLR_SSL_STRCMP(*argv,"-key") == 0) { if (--argc < 1) goto bad; keyfile= *(++argv); } else if (TINYCLR_SSL_STRCMP(*argv,"-challenge") == 0) { if (--argc < 1) goto bad; challenge= *(++argv); } else if (TINYCLR_SSL_STRCMP(*argv,"-spkac") == 0) { if (--argc < 1) goto bad; spkac= *(++argv); } else if (TINYCLR_SSL_STRCMP(*argv,"-spksect") == 0) { if (--argc < 1) goto bad; spksect= *(++argv); } #ifndef OPENSSL_NO_ENGINE else if (TINYCLR_SSL_STRCMP(*argv,"-engine") == 0) { if (--argc < 1) goto bad; engine= *(++argv); } #endif else if (TINYCLR_SSL_STRCMP(*argv,"-noout") == 0) noout=1; else if (TINYCLR_SSL_STRCMP(*argv,"-pubkey") == 0) pubkey=1; else if (TINYCLR_SSL_STRCMP(*argv,"-verify") == 0) verify=1; else badops = 1; argc--; argv++; } if (badops) { bad: BIO_printf(bio_err,"%s [options]\n",prog); BIO_printf(bio_err,"where options are\n"); BIO_printf(bio_err," -in arg input file\n"); BIO_printf(bio_err," -out arg output file\n"); BIO_printf(bio_err," -key arg create SPKAC using private key\n"); BIO_printf(bio_err," -passin arg input file pass phrase source\n"); BIO_printf(bio_err," -challenge arg challenge string\n"); BIO_printf(bio_err," -spkac arg alternative SPKAC name\n"); BIO_printf(bio_err," -noout don't print SPKAC\n"); BIO_printf(bio_err," -pubkey output public key\n"); BIO_printf(bio_err," -verify verify SPKAC signature\n"); #ifndef OPENSSL_NO_ENGINE BIO_printf(bio_err," -engine e use engine e, possibly a hardware device.\n"); #endif goto end; } ERR_load_crypto_strings(); if(!app_passwd(bio_err, passargin, NULL, &passin, NULL)) { BIO_printf(bio_err, "Error getting password\n"); goto end; } #ifndef OPENSSL_NO_ENGINE e = setup_engine(bio_err, engine, 0); #endif if(keyfile) { pkey = load_key(bio_err, TINYCLR_SSL_STRCMP(keyfile, "-") ? keyfile : NULL, FORMAT_PEM, 1, passin, e, "private key"); if(!pkey) { goto end; } spki = NETSCAPE_SPKI_new(); if(challenge) ASN1_STRING_set(spki->spkac->challenge, challenge, (int)TINYCLR_SSL_STRLEN(challenge)); NETSCAPE_SPKI_set_pubkey(spki, pkey); NETSCAPE_SPKI_sign(spki, pkey, EVP_md5()); spkstr = NETSCAPE_SPKI_b64_encode(spki); if (outfile) out = BIO_new_file(outfile, "w"); else { out = BIO_new_fp(OPENSSL_TYPE__FILE_STDOUT, BIO_NOCLOSE); #ifdef OPENSSL_SYS_VMS { BIO *tmpbio = BIO_new(BIO_f_linebuffer()); out = BIO_push(tmpbio, out); } #endif } if(!out) { BIO_printf(bio_err, "Error opening output file\n"); ERR_print_errors(bio_err); goto end; } BIO_printf(out, "SPKAC=%s\n", spkstr); OPENSSL_free(spkstr); ret = 0; goto end; } if (infile) in = BIO_new_file(infile, "r"); else in = BIO_new_fp(OPENSSL_TYPE__FILE_STDIN, BIO_NOCLOSE); if(!in) { BIO_printf(bio_err, "Error opening input file\n"); ERR_print_errors(bio_err); goto end; } conf = NCONF_new(NULL); i = NCONF_load_bio(conf, in, NULL); if(!i) { BIO_printf(bio_err, "Error parsing config file\n"); ERR_print_errors(bio_err); goto end; } spkstr = NCONF_get_string(conf, spksect, spkac); if(!spkstr) { BIO_printf(bio_err, "Can't find SPKAC called \"%s\"\n", spkac); ERR_print_errors(bio_err); goto end; } spki = NETSCAPE_SPKI_b64_decode(spkstr, -1); if(!spki) { BIO_printf(bio_err, "Error loading SPKAC\n"); ERR_print_errors(bio_err); goto end; } if (outfile) out = BIO_new_file(outfile, "w"); else { out = BIO_new_fp(OPENSSL_TYPE__FILE_STDOUT, BIO_NOCLOSE); #ifdef OPENSSL_SYS_VMS { BIO *tmpbio = BIO_new(BIO_f_linebuffer()); out = BIO_push(tmpbio, out); } #endif } if(!out) { BIO_printf(bio_err, "Error opening output file\n"); ERR_print_errors(bio_err); goto end; } if(!noout) NETSCAPE_SPKI_print(out, spki); pkey = NETSCAPE_SPKI_get_pubkey(spki); if(verify) { i = NETSCAPE_SPKI_verify(spki, pkey); if (i > 0) BIO_printf(bio_err, "Signature OK\n"); else { BIO_printf(bio_err, "Signature Failure\n"); ERR_print_errors(bio_err); goto end; } } if(pubkey) PEM_write_bio_PUBKEY(out, pkey); ret = 0; end: NCONF_free(conf); NETSCAPE_SPKI_free(spki); BIO_free(in); BIO_free_all(out); EVP_PKEY_free(pkey); if(passin) OPENSSL_free(passin); apps_shutdown(); OPENSSL_EXIT(ret); }
/* * We need to replace a standard chunk of PKCS7 signature with one mandated * by Authenticode. Problem is, replacing it just like that and then calling * PKCS7_final() would make OpenSSL segfault somewhere in PKCS7_dataFinal(). * So, instead, we call PKCS7_dataInit(), then put our Authenticode-specific * data into BIO it returned, then call PKCS7_dataFinal() - which now somehow * does not panic - and _then_ we replace it in the signature. This technique * was used in sbsigntool by Jeremy Kerr, and might have originated in * osslsigncode. */ static void magic(PKCS7 *pkcs7, const char *digest, size_t digest_len) { BIO *bio, *t_bio; ASN1_TYPE *t; ASN1_STRING *s; CONF *cnf; unsigned char *buf, *tmp; char *digest_hex, *magic_conf, *str; int len, nid, ok; digest_hex = bin2hex(digest, digest_len); /* * Construct the SpcIndirectDataContent chunk. */ nid = OBJ_create("1.3.6.1.4.1.311.2.1.4", NULL, NULL); asprintf(&magic_conf, magic_fmt, digest_hex); if (magic_conf == NULL) err(1, "asprintf"); bio = BIO_new_mem_buf((void *)magic_conf, -1); if (bio == NULL) { ERR_print_errors_fp(stderr); errx(1, "BIO_new_mem_buf(3) failed"); } cnf = NCONF_new(NULL); if (cnf == NULL) { ERR_print_errors_fp(stderr); errx(1, "NCONF_new(3) failed"); } ok = NCONF_load_bio(cnf, bio, NULL); if (ok == 0) { ERR_print_errors_fp(stderr); errx(1, "NCONF_load_bio(3) failed"); } str = NCONF_get_string(cnf, "default", "asn1"); if (str == NULL) { ERR_print_errors_fp(stderr); errx(1, "NCONF_get_string(3) failed"); } t = ASN1_generate_nconf(str, cnf); if (t == NULL) { ERR_print_errors_fp(stderr); errx(1, "ASN1_generate_nconf(3) failed"); } /* * We now have our proprietary piece of ASN.1. Let's do * the actual signing. */ len = i2d_ASN1_TYPE(t, NULL); tmp = buf = calloc(1, len); if (tmp == NULL) err(1, "calloc"); i2d_ASN1_TYPE(t, &tmp); /* * We now have contents of 't' stuffed into memory buffer 'buf'. */ tmp = NULL; t = NULL; t_bio = PKCS7_dataInit(pkcs7, NULL); if (t_bio == NULL) { ERR_print_errors_fp(stderr); errx(1, "PKCS7_dataInit(3) failed"); } BIO_write(t_bio, buf + 2, len - 2); ok = PKCS7_dataFinal(pkcs7, t_bio); if (ok == 0) { ERR_print_errors_fp(stderr); errx(1, "PKCS7_dataFinal(3) failed"); } t = ASN1_TYPE_new(); s = ASN1_STRING_new(); ASN1_STRING_set(s, buf, len); ASN1_TYPE_set(t, V_ASN1_SEQUENCE, s); PKCS7_set0_type_other(pkcs7->d.sign->contents, nid, t); }
int spkac_main(int argc, char **argv) { int i, ret = 1; BIO *in = NULL, *out = NULL; char *passin = NULL; char *spkstr = NULL; CONF *conf = NULL; NETSCAPE_SPKI *spki = NULL; EVP_PKEY *pkey = NULL; if (single_execution) { if (pledge("stdio rpath wpath cpath tty", NULL) == -1) { perror("pledge"); exit(1); } } memset(&spkac_config, 0, sizeof(spkac_config)); spkac_config.spkac = "SPKAC"; spkac_config.spksect = "default"; if (options_parse(argc, argv, spkac_options, NULL, NULL) != 0) { spkac_usage(); return (1); } if (!app_passwd(bio_err, spkac_config.passargin, NULL, &passin, NULL)) { BIO_printf(bio_err, "Error getting password\n"); goto end; } if (spkac_config.keyfile) { pkey = load_key(bio_err, strcmp(spkac_config.keyfile, "-") ? spkac_config.keyfile : NULL, FORMAT_PEM, 1, passin, "private key"); if (!pkey) { goto end; } spki = NETSCAPE_SPKI_new(); if (spkac_config.challenge) ASN1_STRING_set(spki->spkac->challenge, spkac_config.challenge, (int) strlen(spkac_config.challenge)); NETSCAPE_SPKI_set_pubkey(spki, pkey); NETSCAPE_SPKI_sign(spki, pkey, EVP_md5()); spkstr = NETSCAPE_SPKI_b64_encode(spki); if (spkstr == NULL) { BIO_printf(bio_err, "Error encoding SPKAC\n"); ERR_print_errors(bio_err); goto end; } if (spkac_config.outfile) out = BIO_new_file(spkac_config.outfile, "w"); else out = BIO_new_fp(stdout, BIO_NOCLOSE); if (!out) { BIO_printf(bio_err, "Error opening output file\n"); ERR_print_errors(bio_err); } else { BIO_printf(out, "SPKAC=%s\n", spkstr); ret = 0; } free(spkstr); goto end; } if (spkac_config.infile) in = BIO_new_file(spkac_config.infile, "r"); else in = BIO_new_fp(stdin, BIO_NOCLOSE); if (!in) { BIO_printf(bio_err, "Error opening input file\n"); ERR_print_errors(bio_err); goto end; } conf = NCONF_new(NULL); i = NCONF_load_bio(conf, in, NULL); if (!i) { BIO_printf(bio_err, "Error parsing config file\n"); ERR_print_errors(bio_err); goto end; } spkstr = NCONF_get_string(conf, spkac_config.spksect, spkac_config.spkac); if (!spkstr) { BIO_printf(bio_err, "Can't find SPKAC called \"%s\"\n", spkac_config.spkac); ERR_print_errors(bio_err); goto end; } spki = NETSCAPE_SPKI_b64_decode(spkstr, -1); if (!spki) { BIO_printf(bio_err, "Error loading SPKAC\n"); ERR_print_errors(bio_err); goto end; } if (spkac_config.outfile) out = BIO_new_file(spkac_config.outfile, "w"); else { out = BIO_new_fp(stdout, BIO_NOCLOSE); } if (!out) { BIO_printf(bio_err, "Error opening output file\n"); ERR_print_errors(bio_err); goto end; } if (!spkac_config.noout) NETSCAPE_SPKI_print(out, spki); pkey = NETSCAPE_SPKI_get_pubkey(spki); if (spkac_config.verify) { i = NETSCAPE_SPKI_verify(spki, pkey); if (i > 0) BIO_printf(bio_err, "Signature OK\n"); else { BIO_printf(bio_err, "Signature Failure\n"); ERR_print_errors(bio_err); goto end; } } if (spkac_config.pubkey) PEM_write_bio_PUBKEY(out, pkey); ret = 0; end: NCONF_free(conf); NETSCAPE_SPKI_free(spki); BIO_free(in); BIO_free_all(out); EVP_PKEY_free(pkey); free(passin); return (ret); }