+ } 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_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(STDout, "%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(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));
+ }
+#ifndef OPENSSL_NO_MD5
+ else if (subject_hash_old == i) {
+ BIO_printf(STDout, "%08lx\n", X509_subject_name_hash_old(x));
+ }
+#endif
+ else if (issuer_hash == i) {
+ BIO_printf(STDout, "%08lx\n", X509_issuer_name_hash(x));
+ }
+#ifndef OPENSSL_NO_MD5
+ else if (issuer_hash_old == i) {
+ BIO_printf(STDout, "%08lx\n", X509_issuer_name_hash_old(x));
+ }
+#endif
+ 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(STDout, 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];
+ 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(STDout, "%s Fingerprint=",
+ OBJ_nid2sn(EVP_MD_type(fdig)));
+ 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;
+ }
+
+ 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;
+ }
+
+ assert(need_rand);
+ if (!x509_certify(ctx, CAfile, digest, x, xca,
+ CApkey, sigopts,
+ 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, 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(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) {
+ NETSCAPE_X509 nx;
+ ASN1_OCTET_STRING hdr;
+
+ hdr.data = (unsigned char *)NETSCAPE_CERT_HDR;
+ hdr.length = strlen(NETSCAPE_CERT_HDR);
+ nx.header = &hdr;
+ nx.cert = x;
+
+ i = ASN1_item_i2d_bio(ASN1_ITEM_rptr(NETSCAPE_X509), out, &nx);
+ } 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);
+ if (sigopts)
+ 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);
+ if (passin)
+ OPENSSL_free(passin);
+ apps_shutdown();
+ OPENSSL_EXIT(ret);
+}
+
+static ASN1_INTEGER *x509_load_serial(char *CAfile, char *serialfile,
+ int create)
+{
+ char *buf = NULL, *p;
+ ASN1_INTEGER *bs = NULL;
+ BIGNUM *serial = NULL;
+ size_t len;
+
+ len = ((serialfile == NULL)
+ ? (strlen(CAfile) + strlen(POSTFIX) + 1)
+ : (strlen(serialfile))) + 1;
+ buf = OPENSSL_malloc(len);
+ if (buf == NULL) {
+ BIO_printf(bio_err, "out of mem\n");
+ goto end;
+ }
+ if (serialfile == NULL) {
+ BUF_strlcpy(buf, CAfile, len);
+ for (p = buf; *p; p++)
+ if (*p == '.') {
+ *p = '\0';
+ break;
+ }
+ BUF_strlcat(buf, POSTFIX, len);
+ } else
+ BUF_strlcpy(buf, serialfile, len);
+
+ serial = load_serial(buf, create, NULL);
+ if (serial == NULL)
+ goto end;
+
+ if (!BN_add_word(serial, 1)) {
+ BIO_printf(bio_err, "add_word failure\n");
+ goto end;
+ }
+
+ if (!save_serial(buf, NULL, serial, &bs))
+ goto end;
+
+ end:
+ if (buf)
+ OPENSSL_free(buf);
+ BN_free(serial);
+ return bs;
+}