-static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest,
- X509 *x, X509 *xca, EVP_PKEY *pkey, char *serialfile, int create,
- int days, int clrext, LHASH *conf, char *section)
- {
- int ret=0;
- BIO *io=NULL;
- MS_STATIC char buf2[1024];
- char *buf=NULL,*p;
- BIGNUM *serial=NULL;
- ASN1_INTEGER *bs=NULL,bs2;
- X509_STORE_CTX xsc;
- EVP_PKEY *upkey;
-
- upkey = X509_get_pubkey(xca);
- EVP_PKEY_copy_parameters(upkey,pkey);
- EVP_PKEY_free(upkey);
-
- X509_STORE_CTX_init(&xsc,ctx,x,NULL);
- buf=Malloc(EVP_PKEY_size(pkey)*2+
- ((serialfile == NULL)
- ?(strlen(CAfile)+strlen(POSTFIX)+1)
- :(strlen(serialfile)))+1);
- if (buf == NULL) { BIO_printf(bio_err,"out of mem\n"); goto end; }
- if (serialfile == NULL)
- {
- strcpy(buf,CAfile);
- for (p=buf; *p; p++)
- if (*p == '.')
- {
- *p='\0';
- break;
- }
- strcat(buf,POSTFIX);
- }
- else
- strcpy(buf,serialfile);
- serial=BN_new();
- bs=ASN1_INTEGER_new();
- if ((serial == NULL) || (bs == NULL))
- {
- ERR_print_errors(bio_err);
- goto end;
- }
-
- io=BIO_new(BIO_s_file());
- if (io == NULL)
- {
- ERR_print_errors(bio_err);
- goto end;
- }
-
- if (BIO_read_filename(io,buf) <= 0)
- {
- if (!create)
- {
- perror(buf);
- goto end;
- }
- else
- {
- ASN1_INTEGER_set(bs,1);
- BN_one(serial);
- }
- }
- else
- {
- if (!a2i_ASN1_INTEGER(io,bs,buf2,1024))
- {
- BIO_printf(bio_err,"unable to load serial number from %s\n",buf);
- ERR_print_errors(bio_err);
- goto end;
- }
- else
- {
- serial=BN_bin2bn(bs->data,bs->length,serial);
- if (serial == NULL)
- {
- BIO_printf(bio_err,"error converting bin 2 bn");
- goto end;
- }
- }
- }
-
- if (!BN_add_word(serial,1))
- { BIO_printf(bio_err,"add_word failure\n"); goto end; }
- bs2.data=(unsigned char *)buf2;
- bs2.length=BN_bn2bin(serial,bs2.data);
-
- if (BIO_write_filename(io,buf) <= 0)
- {
- BIO_printf(bio_err,"error attempting to write serial number file\n");
- perror(buf);
- goto end;
- }
- i2a_ASN1_INTEGER(io,&bs2);
- BIO_puts(io,"\n");
- BIO_free(io);
- io=NULL;
-
- if (!X509_STORE_add_cert(ctx,x)) goto end;
-
- /* NOTE: this certificate can/should be self signed, unless it was
- * a certificate request in which case it is not. */
- X509_STORE_CTX_set_cert(&xsc,x);
- if (!reqfile && !X509_verify_cert(&xsc))
- goto end;
-
- if (!X509_check_private_key(xca,pkey))
- {
- BIO_printf(bio_err,"CA certificate and CA private key do not match\n");
- goto end;
- }
-
- if (!X509_set_issuer_name(x,X509_get_subject_name(xca))) goto end;
- if (!X509_set_serialNumber(x,bs)) goto end;
-
- if (X509_gmtime_adj(X509_get_notBefore(x),0L) == NULL)
- goto end;
-
- /* hardwired expired */
- if (X509_gmtime_adj(X509_get_notAfter(x),(long)60*60*24*days) == NULL)
- goto end;
-
- if(clrext) {
- while(X509_get_ext_count(x) > 0) X509_delete_ext(x, 0);
- }
-
- if(conf) {
- X509V3_CTX ctx2;
- X509_set_version(x,2); /* version 3 certificate */
- X509V3_set_ctx(&ctx2, xca, x, NULL, NULL, 0);
- X509V3_set_conf_lhash(&ctx2, conf);
- if(!X509V3_EXT_add_conf(conf, &ctx2, section, x)) goto end;
- }
-
- if (!X509_sign(x,pkey,digest)) goto end;
- ret=1;
-end:
- X509_STORE_CTX_cleanup(&xsc);
- if (!ret)
- ERR_print_errors(bio_err);
- if (buf != NULL) Free(buf);
- if (bs != NULL) ASN1_INTEGER_free(bs);
- if (io != NULL) BIO_free(io);
- if (serial != NULL) BN_free(serial);
- return(ret);
- }
-
-static int MS_CALLBACK callb(int ok, X509_STORE_CTX *ctx)
- {
- char buf[256];
- int err;
- X509 *err_cert;
-
- /* it is ok to use a self signed certificate
- * This case will catch both the initial ok == 0 and the
- * final ok == 1 calls to this function */
- err=X509_STORE_CTX_get_error(ctx);
- if (err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT)
- return(1);
-
- /* BAD we should have gotten an error. Normally if everything
- * worked X509_STORE_CTX_get_error(ctx) will still be set to
- * DEPTH_ZERO_SELF_.... */
- if (ok)
- {
- BIO_printf(bio_err,"error with certificate to be certified - should be self signed\n");
- return(0);
- }
- else
- {
- err_cert=X509_STORE_CTX_get_current_cert(ctx);
- X509_NAME_oneline(X509_get_subject_name(err_cert),buf,256);
- BIO_printf(bio_err,"%s\n",buf);
- BIO_printf(bio_err,"error with certificate - error %d at depth %d\n%s\n",
- err,X509_STORE_CTX_get_error_depth(ctx),
- X509_verify_cert_error_string(err));
- return(1);
- }
- }
-
-static EVP_PKEY *load_key(char *file, int format, char *passin)
- {
- BIO *key=NULL;
- EVP_PKEY *pkey=NULL;
-
- if (file == NULL)
- {
- BIO_printf(bio_err,"no keyfile specified\n");
- goto end;
- }
- key=BIO_new(BIO_s_file());
- if (key == NULL)
- {
- ERR_print_errors(bio_err);
- goto end;
- }
- if (BIO_read_filename(key,file) <= 0)
- {
- perror(file);
- goto end;
- }
- if (format == FORMAT_ASN1)
- {
- pkey=d2i_PrivateKey_bio(key, NULL);
- }
- else if (format == FORMAT_PEM)
- {
- pkey=PEM_read_bio_PrivateKey(key,NULL,NULL,passin);
- }
- else
- {
- BIO_printf(bio_err,"bad input format specified for key\n");
- goto end;
- }
-end:
- if (key != NULL) BIO_free(key);
- if (pkey == NULL)
- BIO_printf(bio_err,"unable to load Private Key\n");
- return(pkey);
- }
-
-static X509 *load_cert(char *file, int format)
- {
- ASN1_HEADER *ah=NULL;
- BUF_MEM *buf=NULL;
- X509 *x=NULL;
- BIO *cert;
-
- if ((cert=BIO_new(BIO_s_file())) == NULL)
- {
- ERR_print_errors(bio_err);
- goto end;
- }
-
- if (file == NULL)
- BIO_set_fp(cert,stdin,BIO_NOCLOSE);
- else
- {
- if (BIO_read_filename(cert,file) <= 0)
- {
- perror(file);
- goto end;
- }
- }
- if (format == FORMAT_ASN1)
- x=d2i_X509_bio(cert,NULL);
- else if (format == FORMAT_NETSCAPE)
- {
- unsigned char *p,*op;
- int size=0,i;
-
- /* We sort of have to do it this way because it is sort of nice
- * to read the header first and check it, then
- * try to read the certificate */
- buf=BUF_MEM_new();
- for (;;)
- {
- if ((buf == NULL) || (!BUF_MEM_grow(buf,size+1024*10)))
- goto end;
- i=BIO_read(cert,&(buf->data[size]),1024*10);
- size+=i;
- if (i == 0) break;
- if (i < 0)
- {
- perror("reading certificate");
- goto end;
- }
- }
- p=(unsigned char *)buf->data;
- op=p;
-
- /* First load the header */
- if ((ah=d2i_ASN1_HEADER(NULL,&p,(long)size)) == NULL)
- goto end;
- if ((ah->header == NULL) || (ah->header->data == NULL) ||
- (strncmp(CERT_HDR,(char *)ah->header->data,
- ah->header->length) != 0))
- {
- BIO_printf(bio_err,"Error reading header on certificate\n");
- goto end;
- }
- /* header is ok, so now read the object */
- p=op;
- ah->meth=X509_asn1_meth();
- if ((ah=d2i_ASN1_HEADER(&ah,&p,(long)size)) == NULL)
- goto end;
- x=(X509 *)ah->data;
- ah->data=NULL;
- }
- else if (format == FORMAT_PEM)
- x=PEM_read_bio_X509_AUX(cert,NULL,NULL,NULL);
- else {
- BIO_printf(bio_err,"bad input format specified for input cert\n");
- goto end;
- }
-end:
- if (x == NULL)
- {
- BIO_printf(bio_err,"unable to load certificate\n");
- ERR_print_errors(bio_err);
- }
- if (ah != NULL) ASN1_HEADER_free(ah);
- if (cert != NULL) BIO_free(cert);
- if (buf != NULL) BUF_MEM_free(buf);
- return(x);
- }
+ 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_PEMDER, &CAkeyformat))
+ goto opthelp;
+ break;
+ case OPT_OUT:
+ outfile = opt_arg();
+ break;
+ case OPT_REQ:
+ reqfile = need_rand = 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_FORCE_VERSION:
+#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL
+ force_version = atoi(opt_arg()) - 1;
+#endif
+ break;
+ case OPT_DAYS:
+ days = atoi(opt_arg());
+ break;
+ case OPT_PASSIN:
+ passinarg = opt_arg();
+ break;
+ case OPT_EXTFILE:
+ extfile = opt_arg();
+ break;
+ case OPT_EXTENSIONS:
+ extsect = opt_arg();
+ break;
+ case OPT_SIGNKEY:
+ keyfile = opt_arg();
+ sign_flag = ++num;
+ need_rand = 1;
+ break;
+ case OPT_CA:
+ CAfile = opt_arg();
+ CA_flag = ++num;
+ need_rand = 1;
+ break;
+ case OPT_CAKEY:
+ CAkeyfile = opt_arg();
+ break;
+ case OPT_CASERIAL:
+ CAserial = opt_arg();
+ break;
+ case OPT_SET_SERIAL:
+ 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);
+ 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);
+ 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:
+ nmflag_set = 1;
+ if (!set_name_ex(&nmflag, 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_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:
+ checkoffset = atoi(opt_arg());
+ checkend = 1;
+ break;
+ case OPT_CHECKHOST:
+ checkhost = opt_arg();
+ break;
+ case OPT_CHECKEMAIL:
+ checkemail = opt_arg();
+ break;
+ case OPT_CHECKIP:
+ checkip = opt_arg();
+ 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 (!nmflag_set)
+ nmflag = XN_FLAG_ONELINE;
+
+ if (!app_load_modules(NULL))
+ goto end;
+
+ out = bio_open_default(outfile, "w");
+ if (out == NULL)
+ goto end;
+
+ if (need_rand)
+ app_RAND_load_file(NULL, 0);
+
+ 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) {
+ 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) {
+ X509V3_CTX ctx2;
+ if ((extconf = app_load_config(extfile)) == NULL)
+ 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_open_default(infile, "r");
+ 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 ((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_time_adj_ex(X509_get_notAfter(x), days, 0, NULL);
+ if (fkey)
+ X509_set_pubkey(x, fkey);
+ else {
+ pkey = X509_REQ_get_pubkey(req);
+ X509_set_pubkey(x, pkey);
+ EVP_PKEY_free(pkey);
+ }
+ } else
+ x = load_cert(infile, informat, NULL, e, "Certificate");
+
+ if (x == NULL)
+ goto end;
+ if (CA_flag) {
+ xca = load_cert(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");
+
+ }
+
+ 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(out, "issuer= ", X509_get_issuer_name(x), nmflag);
+ } else if (subject == i) {
+ print_name(out, "subject= ",
+ X509_get_subject_name(x), nmflag);
+ } 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) {
+ 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_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_get_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 (pkey->type == EVP_PKEY_RSA)
+ BN_print(out, pkey->pkey.rsa->n);
+ else
+#endif
+#ifndef OPENSSL_NO_DSA
+ if (pkey->type == EVP_PKEY_DSA)
+ BN_print(out, pkey->pkey.dsa->pub_key);
+ else
+#endif
+ BIO_printf(out, "Wrong Algorithm type");
+ BIO_printf(out, "\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(out, pkey);
+ EVP_PKEY_free(pkey);
+ } else if (C == i) {
+ unsigned char *d;
+ char *m;
+ int len;
+
+ X509_NAME_oneline(X509_get_subject_name(x), buf, sizeof buf);
+ BIO_printf(out, "/*\n"
+ " * Subject: %s\n", buf);
+
+ m = X509_NAME_oneline(X509_get_issuer_name(x), buf, sizeof buf);
+ BIO_printf(out, " * Issuer: %s\n"
+ " */\n", buf);
+
+ 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, nmflag, certflag);
+ } else if (startdate == i) {
+ BIO_puts(out, "notBefore=");
+ ASN1_TIME_print(out, X509_get_notBefore(x));
+ BIO_puts(out, "\n");
+ } else if (enddate == i) {
+ BIO_puts(out, "notAfter=");
+ ASN1_TIME_print(out, X509_get_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)
+ 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;
+ }