/**
 * Module deactivation
 *
 */
static
int
globus_l_openssl_deactivate(void)
{
    int                                 i;

    OBJ_cleanup();

    ERR_clear_error();

    X509V3_EXT_cleanup();

    if (CRYPTO_get_id_callback() == globus_l_openssl_thread_id)
    {
        CRYPTO_set_id_callback(NULL);
    }
    if (CRYPTO_get_locking_callback() == globus_l_openssl_locking_cb)
    {
        CRYPTO_set_locking_callback(NULL);
    }

    for (i=0; i<CRYPTO_num_locks(); i++)
    {
        globus_mutex_destroy(&(mutex_pool[i]));
    }

    free(mutex_pool);

    globus_module_deactivate(GLOBUS_GSI_OPENSSL_ERROR_MODULE);
    globus_module_deactivate(GLOBUS_COMMON_MODULE);

    return GLOBUS_SUCCESS;
}
Exemple #2
0
int main()
{
    BIO *bio_err;
    X509 *x509 = NULL;
    EVP_PKEY *pkey = NULL;

    CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);

    bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);

    mkit(&x509, &pkey, 512, 0, 365);

    RSA_print_fp(stdout, pkey->pkey.rsa, 0);
    X509_print_fp(stdout, x509);

    PEM_write_PrivateKey(stdout, pkey, NULL, NULL, 0, NULL, NULL);
    PEM_write_X509(stdout, x509);

    X509_free(x509);
    EVP_PKEY_free(pkey);

#ifdef CUSTOM_EXT
    /* Only needed if we add objects or custom extensions */
    X509V3_EXT_cleanup();
    OBJ_cleanup();
#endif

    CRYPTO_mem_leaks(bio_err);
    BIO_free(bio_err);
    return (0);
}
EXPORT void STDCALL TaggantFinalizeLibrary(void)
{
    lib_initialized = 0;
    OBJ_cleanup();
    EVP_cleanup();
    CRYPTO_cleanup_all_ex_data();
    ERR_remove_thread_state(NULL);
    ERR_free_strings();
}
Exemple #4
0
void openssl_cleanup()
{
    CONF_modules_unload(1);
    OBJ_cleanup();
    EVP_cleanup();
    ENGINE_cleanup();
    CRYPTO_cleanup_all_ex_data();
    ERR_remove_state(0);
    ERR_free_strings();
}
Exemple #5
0
/*
 * Make sure openssl does not introduce memory leaks for valgrind
 */
__attribute__((destructor)) void cleanup_openssl (void)
{
    //http://www.openssl.org/support/faq.html#PROG13
    ERR_remove_thread_state(NULL);
    ENGINE_cleanup();
    CONF_modules_unload(1);
    ERR_free_strings();
    OBJ_cleanup();
    EVP_cleanup();
    CRYPTO_cleanup_all_ex_data();
}
Exemple #6
0
static void
openssl_shutdown(void)
{
	CONF_modules_unload(1);
	destroy_ui();
	OBJ_cleanup();
	EVP_cleanup();
	CRYPTO_cleanup_all_ex_data();
	ERR_remove_thread_state(NULL);
	ERR_free_strings();
}
Exemple #7
0
static int luaclose_openssl(lua_State *L)
{
  if(atomic_fetch_sub(&init, 1) > 1)
    return 0;

#if !defined(LIBRESSL_VERSION_NUMBER)
  FIPS_mode_set(0);
#endif

  OBJ_cleanup();
  EVP_cleanup();
  ENGINE_cleanup();
  RAND_cleanup();

#if OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined(LIBRESSL_VERSION_NUMBER)
  SSL_COMP_free_compression_methods();
#endif
  COMP_zlib_cleanup();


#if OPENSSL_VERSION_NUMBER < 0x10000000L
  ERR_remove_state(0);
#elif OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
  ERR_remove_thread_state(NULL);
#endif
#if defined(OPENSSL_THREADS)
  CRYPTO_thread_cleanup();
#endif
  CRYPTO_set_locking_callback(NULL);
  CRYPTO_set_id_callback(NULL);

  CRYPTO_cleanup_all_ex_data();
  ERR_free_strings();

  CONF_modules_free();
  CONF_modules_unload(1);
#ifndef OPENSSL_NO_CRYPTO_MDEBUG
#if !(defined(OPENSSL_NO_STDIO) || defined(OPENSSL_NO_FP_API))
#if defined(LIBRESSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x10101000L
  CRYPTO_mem_leaks_fp(stderr);
#else
  if(CRYPTO_mem_leaks_fp(stderr)!=1)
  {
    fprintf(stderr,
            "Please report a bug on https://github.com/zhaozg/lua-openssl."
            "And if can, please provide a reproduce method and minimal code.\n"
            "\n\tThank You.");
  }
#endif
#endif /* OPENSSL_NO_STDIO or OPENSSL_NO_FP_API */
#endif /* OPENSSL_NO_CRYPTO_MDEBUG */
  return 0;
}
Exemple #8
0
static apr_status_t ssl_cleanup_pre_config(void *data)
{
    /*
     * Try to kill the internals of the SSL library.
     */
#ifdef HAVE_FIPS
    FIPS_mode_set(0);
#endif
    /* Corresponds to OBJ_create()s */
    OBJ_cleanup();
    /* Corresponds to OPENSSL_load_builtin_modules() */
    CONF_modules_free();
    /* Corresponds to SSL_library_init: */
    EVP_cleanup();
#if HAVE_ENGINE_LOAD_BUILTIN_ENGINES
    ENGINE_cleanup();
#endif
#if OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined(OPENSSL_NO_COMP)
    SSL_COMP_free_compression_methods();
#endif

    /* Usually needed per thread, but this parent process is single-threaded */
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
#if OPENSSL_VERSION_NUMBER >= 0x1000000fL
    ERR_remove_thread_state(NULL);
#else
    ERR_remove_state(0);
#endif
#endif

    /* Don't call ERR_free_strings in earlier versions, ERR_load_*_strings only
     * actually loaded the error strings once per process due to static
     * variable abuse in OpenSSL. */
#if (OPENSSL_VERSION_NUMBER >= 0x00090805f)
    ERR_free_strings();
#endif

    /* Also don't call CRYPTO_cleanup_all_ex_data when linked statically here;
     * any registered ex_data indices may have been cached in static variables
     * in OpenSSL; removing them may cause havoc.  Notably, with OpenSSL
     * versions >= 0.9.8f, COMP_CTX cleanups would not be run, which
     * could result in a per-connection memory leak (!). */
    if (!modssl_running_statically) {
        CRYPTO_cleanup_all_ex_data();
    }

    /*
     * TODO: determine somewhere we can safely shove out diagnostics
     *       (when enabled) at this late stage in the game:
     * CRYPTO_mem_leaks_fp(stderr);
     */
    return APR_SUCCESS;
}
Exemple #9
0
void GT_finalize(void)
{
	if (--init_count > 0) {
		/* Do nothing: still being used by someone. */
		return;
	}
	/* In theory we should also check for init_count < 0, but
	 * in practice nothing could be done in this case... */

	threadCleanup();
	OBJ_cleanup();
	ERR_free_strings();
	ERR_remove_state(0);
	EVP_cleanup();
	CRYPTO_cleanup_all_ex_data();
}
Exemple #10
0
void
EVP_cleanup(void)
{
	OBJ_NAME_cleanup(OBJ_NAME_TYPE_CIPHER_METH);
	OBJ_NAME_cleanup(OBJ_NAME_TYPE_MD_METH);
	/* The above calls will only clean out the contents of the name
	   hash table, but not the hash table itself.  The following line
	   does that part.  -- Richard Levitte */
	OBJ_NAME_cleanup(-1);

	EVP_PBE_cleanup();
	if (obj_cleanup_defer == 2) {
		obj_cleanup_defer = 0;
		OBJ_cleanup();
	}
	OBJ_sigid_free();
}
static void
openssl_shutdown(void)
{
	CONF_modules_unload(1);
	destroy_ui_method();
	OBJ_cleanup();
	EVP_cleanup();

#ifndef OPENSSL_NO_ENGINE
	ENGINE_cleanup();
#endif

	CRYPTO_cleanup_all_ex_data();
	ERR_remove_thread_state(NULL);
	RAND_cleanup();
	ERR_free_strings();
}
Exemple #12
0
void
dst__openssl_destroy(void) {
	/*
	 * Sequence taken from apps_shutdown() in <apps/apps.h>.
	 */
	if (rm != NULL) {
#if OPENSSL_VERSION_NUMBER >= 0x00907000L
		RAND_cleanup();
#endif
		mem_free(rm);
		rm = NULL;
	}
#if (OPENSSL_VERSION_NUMBER >= 0x00907000L)
	CONF_modules_free();
#endif
	OBJ_cleanup();
	EVP_cleanup();
#if defined(USE_ENGINE)
	if (e != NULL)
		ENGINE_free(e);
	e = NULL;
#if defined(USE_ENGINE) && OPENSSL_VERSION_NUMBER >= 0x00907000L
	ENGINE_cleanup();
#endif
#endif
#if (OPENSSL_VERSION_NUMBER >= 0x00907000L)
	CRYPTO_cleanup_all_ex_data();
#endif
	ERR_clear_error();
#if OPENSSL_VERSION_NUMBER < 0x10100000L
	ERR_remove_state(0);
#endif
	ERR_free_strings();

#ifdef  DNS_CRYPTO_LEAKS
	CRYPTO_mem_leaks_fp(stderr);
#endif

	if (locks != NULL) {
		CRYPTO_set_locking_callback(NULL);
		DESTROYMUTEXBLOCK(locks, nlocks);
		mem_free(locks);
		locks = NULL;
	}
}
Exemple #13
0
static void apps_shutdown()
{
#ifndef OPENSSL_NO_ENGINE
    ENGINE_cleanup();
#endif
    destroy_ui_method();
    CONF_modules_unload(1);
#ifndef OPENSSL_NO_COMP
    COMP_zlib_cleanup();
    SSL_COMP_free_compression_methods();
#endif
    OBJ_cleanup();
    EVP_cleanup();
    CRYPTO_cleanup_all_ex_data();
    ERR_remove_thread_state(NULL);
    RAND_cleanup();
    ERR_free_strings();
}
Exemple #14
0
int x509_main(int argc, char **argv)
{
    ASN1_INTEGER *sno = NULL;
    ASN1_OBJECT *objtmp;
    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;
    char *extsect = NULL, *extfile = NULL, *passin = NULL, *passinarg = NULL;
    char *infile = NULL, *outfile = NULL, *keyfile = NULL, *CAfile = NULL;
    char buf[256], *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, need_rand = 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;
    int checkoffset = 0, enddate = 0;
    unsigned long nmflag = 0, certflag = 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_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;
#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL
        case OPT_FORCE_VERSION:
            force_version = atoi(opt_arg()) - 1;
            break;
#endif
        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:
            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;
#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;
    }

    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) {
        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_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;
                }

                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(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, reqfile))
                    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(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;
    }

    print_cert_checks(out, x, checkhost, checkemail, checkip);

    if (noout || nocert) {
        ret = 0;
        goto end;
    }

    if (badsig)
        x->signature->data[x->signature->length - 1] ^= 0x1;

    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);
    OBJ_cleanup();
    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);
    OPENSSL_free(passin);
    return (ret);
}
Exemple #15
0
int
ts_main(int argc, char **argv)
{
	int ret = 1;
	char *configfile = NULL;
	char *section = NULL;
	CONF *conf = NULL;
	enum mode {
		CMD_NONE, CMD_QUERY, CMD_REPLY, CMD_VERIFY
	} mode = CMD_NONE;
	char *data = NULL;
	char *digest = NULL;
	const EVP_MD *md = NULL;
	char *policy = NULL;
	int no_nonce = 0;
	int cert = 0;
	char *in = NULL;
	char *out = NULL;
	int text = 0;
	char *queryfile = NULL;
	char *passin = NULL;	/* Password source. */
	char *password = NULL;	/* Password itself. */
	char *inkey = NULL;
	char *signer = NULL;
	char *chain = NULL;
	char *ca_path = NULL;
	char *ca_file = NULL;
	char *untrusted = NULL;
	char *engine = NULL;
	/* Input is ContentInfo instead of TimeStampResp. */
	int token_in = 0;
	/* Output is ContentInfo instead of TimeStampResp. */
	int token_out = 0;

	for (argc--, argv++; argc > 0; argc--, argv++) {
		if (strcmp(*argv, "-config") == 0) {
			if (argc-- < 1)
				goto usage;
			configfile = *++argv;
		} else if (strcmp(*argv, "-section") == 0) {
			if (argc-- < 1)
				goto usage;
			section = *++argv;
		} else if (strcmp(*argv, "-query") == 0) {
			if (mode != CMD_NONE)
				goto usage;
			mode = CMD_QUERY;
		} else if (strcmp(*argv, "-data") == 0) {
			if (argc-- < 1)
				goto usage;
			data = *++argv;
		} else if (strcmp(*argv, "-digest") == 0) {
			if (argc-- < 1)
				goto usage;
			digest = *++argv;
		} else if (strcmp(*argv, "-policy") == 0) {
			if (argc-- < 1)
				goto usage;
			policy = *++argv;
		} else if (strcmp(*argv, "-no_nonce") == 0) {
			no_nonce = 1;
		} else if (strcmp(*argv, "-cert") == 0) {
			cert = 1;
		} else if (strcmp(*argv, "-in") == 0) {
			if (argc-- < 1)
				goto usage;
			in = *++argv;
		} else if (strcmp(*argv, "-token_in") == 0) {
			token_in = 1;
		} else if (strcmp(*argv, "-out") == 0) {
			if (argc-- < 1)
				goto usage;
			out = *++argv;
		} else if (strcmp(*argv, "-token_out") == 0) {
			token_out = 1;
		} else if (strcmp(*argv, "-text") == 0) {
			text = 1;
		} else if (strcmp(*argv, "-reply") == 0) {
			if (mode != CMD_NONE)
				goto usage;
			mode = CMD_REPLY;
		} else if (strcmp(*argv, "-queryfile") == 0) {
			if (argc-- < 1)
				goto usage;
			queryfile = *++argv;
		} else if (strcmp(*argv, "-passin") == 0) {
			if (argc-- < 1)
				goto usage;
			passin = *++argv;
		} else if (strcmp(*argv, "-inkey") == 0) {
			if (argc-- < 1)
				goto usage;
			inkey = *++argv;
		} else if (strcmp(*argv, "-signer") == 0) {
			if (argc-- < 1)
				goto usage;
			signer = *++argv;
		} else if (strcmp(*argv, "-chain") == 0) {
			if (argc-- < 1)
				goto usage;
			chain = *++argv;
		} else if (strcmp(*argv, "-verify") == 0) {
			if (mode != CMD_NONE)
				goto usage;
			mode = CMD_VERIFY;
		} else if (strcmp(*argv, "-CApath") == 0) {
			if (argc-- < 1)
				goto usage;
			ca_path = *++argv;
		} else if (strcmp(*argv, "-CAfile") == 0) {
			if (argc-- < 1)
				goto usage;
			ca_file = *++argv;
		} else if (strcmp(*argv, "-untrusted") == 0) {
			if (argc-- < 1)
				goto usage;
			untrusted = *++argv;
		} else if (strcmp(*argv, "-engine") == 0) {
			if (argc-- < 1)
				goto usage;
			engine = *++argv;
		} else if ((md = EVP_get_digestbyname(*argv + 1)) != NULL) {
			/* empty. */
		} else
			goto usage;
	}

	/* Get the password if required. */
	if (mode == CMD_REPLY && passin &&
	    !app_passwd(bio_err, passin, NULL, &password, NULL)) {
		BIO_printf(bio_err, "Error getting password.\n");
		goto cleanup;
	}
	/*
	 * Check consistency of parameters and execute the appropriate
	 * function.
	 */
	switch (mode) {
	case CMD_NONE:
		goto usage;
	case CMD_QUERY:
		/*
		 * Data file and message imprint cannot be specified at the
		 * same time.
		 */
		ret = data != NULL && digest != NULL;
		if (ret)
			goto usage;
		/* Load the config file for possible policy OIDs. */
		conf = load_config_file(configfile);
		ret = !query_command(data, digest, md, policy, no_nonce, cert,
		    in, out, text);
		break;
	case CMD_REPLY:
		conf = load_config_file(configfile);
		if (in == NULL) {
			ret = !(queryfile != NULL && conf != NULL && !token_in);
			if (ret)
				goto usage;
		} else {
			/* 'in' and 'queryfile' are exclusive. */
			ret = !(queryfile == NULL);
			if (ret)
				goto usage;
		}

		ret = !reply_command(conf, section, engine, queryfile,
		    password, inkey, signer, chain, policy,
		    in, token_in, out, token_out, text);
		break;
	case CMD_VERIFY:
		ret = !(((queryfile && !data && !digest) ||
		    (!queryfile && data && !digest) ||
		    (!queryfile && !data && digest)) && in != NULL);
		if (ret)
			goto usage;

		ret = !verify_command(data, digest, queryfile, in, token_in,
		    ca_path, ca_file, untrusted);
	}

	goto cleanup;

usage:
	BIO_printf(bio_err, "usage:\n"
	    "ts -query [-config configfile] "
	    "[-data file_to_hash] [-digest digest_bytes]"
	    "[-md2|-md4|-md5|-sha|-sha1|-ripemd160] "
	    "[-policy object_id] [-no_nonce] [-cert] "
	    "[-in request.tsq] [-out request.tsq] [-text]\n");
	BIO_printf(bio_err, "or\n"
	    "ts -reply [-config configfile] [-section tsa_section] "
	    "[-queryfile request.tsq] [-passin password] "
	    "[-signer tsa_cert.pem] [-inkey private_key.pem] "
	    "[-chain certs_file.pem] [-policy object_id] "
	    "[-in response.tsr] [-token_in] "
	    "[-out response.tsr] [-token_out] [-text] [-engine id]\n");
	BIO_printf(bio_err, "or\n"
	    "ts -verify [-data file_to_hash] [-digest digest_bytes] "
	    "[-queryfile request.tsq] "
	    "-in response.tsr [-token_in] "
	    "-CApath ca_path -CAfile ca_file.pem "
	    "-untrusted cert_file.pem\n");

cleanup:
	/* Clean up. */
	NCONF_free(conf);
	free(password);
	OBJ_cleanup();

	return (ret);
}
Exemple #16
0
int srp_main(int argc, char **argv)
{
    CA_DB *db = NULL;
    DB_ATTR db_attr;
    CONF *conf = NULL;
    int gNindex = -1, maxgN = -1, ret = 1, errors = 0, verbose =
        0, i, doupdatedb = 0;
    int mode = OPT_ERR;
    char *user = NULL, *passinarg = NULL, *passoutarg = NULL;
    char *passin = NULL, *passout = NULL, *gN = NULL, *userinfo = NULL;
    char *randfile = NULL, *tofree = NULL, *section = NULL;
    char **gNrow = NULL, *configfile = NULL, *dbfile = NULL, **pp, *prog;
    long errorline = -1;
    OPTION_CHOICE o;

    prog = opt_init(argc, argv, srp_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(srp_options);
            ret = 0;
            goto end;
        case OPT_VERBOSE:
            verbose++;
            break;
        case OPT_CONFIG:
            configfile = opt_arg();
            break;
        case OPT_NAME:
            section = opt_arg();
            break;
        case OPT_SRPVFILE:
            dbfile = opt_arg();
            break;
        case OPT_ADD:
        case OPT_DELETE:
        case OPT_MODIFY:
        case OPT_LIST:
            if (mode != OPT_ERR) {
                BIO_printf(bio_err,
                           "%s: Only one of -add/delete-modify/-list\n",
                           prog);
                goto opthelp;
            }
            mode = o;
            break;
        case OPT_GN:
            gN = opt_arg();
            break;
        case OPT_USERINFO:
            userinfo = opt_arg();
            break;
        case OPT_PASSIN:
            passinarg = opt_arg();
            break;
        case OPT_PASSOUT:
            passoutarg = opt_arg();
            break;
        case OPT_ENGINE:
            (void)setup_engine(opt_arg(), 0);
            break;
        }
    }
    argc = opt_num_rest();
    argv = opt_rest();

    if (dbfile && configfile) {
        BIO_printf(bio_err,
                   "-dbfile and -configfile cannot be specified together.\n");
        goto end;
    }
    if (mode == OPT_ERR) {
        BIO_printf(bio_err,
                   "Exactly one of the options -add, -delete, -modify -list must be specified.\n");
        goto opthelp;
    }
    if ((mode == OPT_DELETE || mode == OPT_MODIFY || mode == OPT_ADD)
        && argc < 1) {
        BIO_printf(bio_err,
                   "Need at least one user for options -add, -delete, -modify. \n");
        goto opthelp;
    }
    if ((passin || passout) && argc != 1) {
        BIO_printf(bio_err,
                   "-passin, -passout arguments only valid with one user.\n");
        goto opthelp;
    }

    if (!app_passwd(passinarg, passoutarg, &passin, &passout)) {
        BIO_printf(bio_err, "Error getting passwords\n");
        goto end;
    }

    if (!dbfile) {

        /*****************************************************************/
        tofree = NULL;
        if (configfile == NULL)
            configfile = getenv("OPENSSL_CONF");
        if (configfile == NULL)
            configfile = getenv("SSLEAY_CONF");
        if (configfile == NULL) {
            const char *s = X509_get_default_cert_area();
            size_t len = strlen(s) + 1 + sizeof(CONFIG_FILE);

            tofree = app_malloc(len, "config filename space");
# ifdef OPENSSL_SYS_VMS
            strcpy(tofree, s);
# else
            BUF_strlcpy(tofree, s, len);
            BUF_strlcat(tofree, "/", len);
# endif
            BUF_strlcat(tofree, CONFIG_FILE, len);
            configfile = tofree;
        }

        if (verbose)
            BIO_printf(bio_err, "Using configuration from %s\n", configfile);
        conf = NCONF_new(NULL);
        if (NCONF_load(conf, configfile, &errorline) <= 0) {
            if (errorline <= 0)
                BIO_printf(bio_err, "error loading the config file '%s'\n",
                           configfile);
            else
                BIO_printf(bio_err, "error on line %ld of config file '%s'\n",
                           errorline, configfile);
            goto end;
        }
        OPENSSL_free(tofree);
        tofree = NULL;

        /* Lets get the config section we are using */
        if (section == NULL) {
            if (verbose)
                BIO_printf(bio_err,
                           "trying to read " ENV_DEFAULT_SRP
                           " in \" BASE_SECTION \"\n");

            section = NCONF_get_string(conf, BASE_SECTION, ENV_DEFAULT_SRP);
            if (section == NULL) {
                lookup_fail(BASE_SECTION, ENV_DEFAULT_SRP);
                goto end;
            }
        }

        if (randfile == NULL && conf)
            randfile = NCONF_get_string(conf, BASE_SECTION, "RANDFILE");

        if (verbose)
            BIO_printf(bio_err,
                       "trying to read " ENV_DATABASE " in section \"%s\"\n",
                       section);

        if ((dbfile = NCONF_get_string(conf, section, ENV_DATABASE)) == NULL) {
            lookup_fail(section, ENV_DATABASE);
            goto end;
        }

    }
    if (randfile == NULL)
        ERR_clear_error();
    else
        app_RAND_load_file(randfile, 0);

    if (verbose)
        BIO_printf(bio_err, "Trying to read SRP verifier file \"%s\"\n",
                   dbfile);

    db = load_index(dbfile, &db_attr);
    if (db == NULL)
        goto end;

    /* Lets check some fields */
    for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) {
        pp = sk_OPENSSL_PSTRING_value(db->db->data, i);

        if (pp[DB_srptype][0] == DB_SRP_INDEX) {
            maxgN = i;
            if ((gNindex < 0) && (gN != NULL) && strcmp(gN, pp[DB_srpid]) == 0)
                gNindex = i;

            print_index(db, i, verbose > 1);
        }
    }

    if (verbose)
        BIO_printf(bio_err, "Database initialised\n");

    if (gNindex >= 0) {
        gNrow = sk_OPENSSL_PSTRING_value(db->db->data, gNindex);
        print_entry(db, gNindex, verbose > 1, "Default g and N");
    } else if (maxgN > 0 && !SRP_get_default_gN(gN)) {
        BIO_printf(bio_err, "No g and N value for index \"%s\"\n", gN);
        goto end;
    } else {
        if (verbose)
            BIO_printf(bio_err, "Database has no g N information.\n");
        gNrow = NULL;
    }

    if (verbose > 1)
        BIO_printf(bio_err, "Starting user processing\n");

    if (argc > 0)
        user = *(argv++);

    while (mode == OPT_LIST || user) {
        int userindex = -1;
        if (user)
            if (verbose > 1)
                BIO_printf(bio_err, "Processing user \"%s\"\n", user);
        if ((userindex = get_index(db, user, 'U')) >= 0) {
            print_user(db, userindex, (verbose > 0)
                       || mode == OPT_LIST);
        }

        if (mode == OPT_LIST) {
            if (user == NULL) {
                BIO_printf(bio_err, "List all users\n");

                for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) {
                    print_user(db, i, 1);
                }
            } else if (userindex < 0) {
                BIO_printf(bio_err,
                           "user \"%s\" does not exist, ignored. t\n", user);
                errors++;
            }
        } else if (mode == OPT_ADD) {
            if (userindex >= 0) {
                /* reactivation of a new user */
                char **row =
                    sk_OPENSSL_PSTRING_value(db->db->data, userindex);
                BIO_printf(bio_err, "user \"%s\" reactivated.\n", user);
                row[DB_srptype][0] = 'V';

                doupdatedb = 1;
            } else {
                char *row[DB_NUMBER];
                char *gNid;
                row[DB_srpverifier] = NULL;
                row[DB_srpsalt] = NULL;
                row[DB_srpinfo] = NULL;
                if (!
                    (gNid =
                     srp_create_user(user, &(row[DB_srpverifier]),
                                     &(row[DB_srpsalt]),
                                     gNrow ? gNrow[DB_srpsalt] : gN,
                                     gNrow ? gNrow[DB_srpverifier] : NULL,
                                     passout, verbose))) {
                    BIO_printf(bio_err,
                               "Cannot create srp verifier for user \"%s\", operation abandoned .\n",
                               user);
                    errors++;
                    goto end;
                }
                row[DB_srpid] = BUF_strdup(user);
                row[DB_srptype] = BUF_strdup("v");
                row[DB_srpgN] = BUF_strdup(gNid);

                if ((row[DB_srpid] == NULL)
                    || (row[DB_srpgN] == NULL)
                    || (row[DB_srptype] == NULL)
                    || (row[DB_srpverifier] == NULL)
                    || (row[DB_srpsalt] == NULL)
                    || (userinfo
                        && ((row[DB_srpinfo] = BUF_strdup(userinfo)) == NULL))
                    || !update_index(db, row)) {
                    OPENSSL_free(row[DB_srpid]);
                    OPENSSL_free(row[DB_srpgN]);
                    OPENSSL_free(row[DB_srpinfo]);
                    OPENSSL_free(row[DB_srptype]);
                    OPENSSL_free(row[DB_srpverifier]);
                    OPENSSL_free(row[DB_srpsalt]);
                    goto end;
                }
                doupdatedb = 1;
            }
        } else if (mode == OPT_MODIFY) {
            if (userindex < 0) {
                BIO_printf(bio_err,
                           "user \"%s\" does not exist, operation ignored.\n",
                           user);
                errors++;
            } else {

                char **row =
                    sk_OPENSSL_PSTRING_value(db->db->data, userindex);
                char type = row[DB_srptype][0];
                if (type == 'v') {
                    BIO_printf(bio_err,
                               "user \"%s\" already updated, operation ignored.\n",
                               user);
                    errors++;
                } else {
                    char *gNid;

                    if (row[DB_srptype][0] == 'V') {
                        int user_gN;
                        char **irow = NULL;
                        if (verbose)
                            BIO_printf(bio_err,
                                       "Verifying password for user \"%s\"\n",
                                       user);
                        if ((user_gN =
                             get_index(db, row[DB_srpgN], DB_SRP_INDEX)) >= 0)
                            irow =
                                sk_OPENSSL_PSTRING_value(db->db->data,
                                                         userindex);

                        if (!srp_verify_user
                            (user, row[DB_srpverifier], row[DB_srpsalt],
                             irow ? irow[DB_srpsalt] : row[DB_srpgN],
                             irow ? irow[DB_srpverifier] : NULL, passin,
                             verbose)) {
                            BIO_printf(bio_err,
                                       "Invalid password for user \"%s\", operation abandoned.\n",
                                       user);
                            errors++;
                            goto end;
                        }
                    }
                    if (verbose)
                        BIO_printf(bio_err, "Password for user \"%s\" ok.\n",
                                   user);

                    if (!
                        (gNid =
                         srp_create_user(user, &(row[DB_srpverifier]),
                                         &(row[DB_srpsalt]),
                                         gNrow ? gNrow[DB_srpsalt] : NULL,
                                         gNrow ? gNrow[DB_srpverifier] : NULL,
                                         passout, verbose))) {
                        BIO_printf(bio_err,
                                   "Cannot create srp verifier for user \"%s\", operation abandoned.\n",
                                   user);
                        errors++;
                        goto end;
                    }

                    row[DB_srptype][0] = 'v';
                    row[DB_srpgN] = BUF_strdup(gNid);

                    if (row[DB_srpid] == NULL
                        || row[DB_srpgN] == NULL
                        || row[DB_srptype] == NULL
                        || row[DB_srpverifier] == NULL
                        || row[DB_srpsalt] == NULL
                        || (userinfo
                            && ((row[DB_srpinfo] = BUF_strdup(userinfo))
                                == NULL)))
                        goto end;

                    doupdatedb = 1;
                }
            }
        } else if (mode == OPT_DELETE) {
            if (userindex < 0) {
                BIO_printf(bio_err,
                           "user \"%s\" does not exist, operation ignored. t\n",
                           user);
                errors++;
            } else {
                char **xpp = sk_OPENSSL_PSTRING_value(db->db->data, userindex);

                BIO_printf(bio_err, "user \"%s\" revoked. t\n", user);
                xpp[DB_srptype][0] = 'R';
                doupdatedb = 1;
            }
        }
        if (--argc > 0)
            user = *(argv++);
        else {
            user = NULL;
        }
    }

    if (verbose)
        BIO_printf(bio_err, "User procession done.\n");

    if (doupdatedb) {
        /* Lets check some fields */
        for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) {
            pp = sk_OPENSSL_PSTRING_value(db->db->data, i);

            if (pp[DB_srptype][0] == 'v') {
                pp[DB_srptype][0] = 'V';
                print_user(db, i, verbose);
            }
        }

        if (verbose)
            BIO_printf(bio_err, "Trying to update srpvfile.\n");
        if (!save_index(dbfile, "new", db))
            goto end;

        if (verbose)
            BIO_printf(bio_err, "Temporary srpvfile created.\n");
        if (!rotate_index(dbfile, "new", "old"))
            goto end;

        if (verbose)
            BIO_printf(bio_err, "srpvfile updated.\n");
    }

    ret = (errors != 0);
 end:
    if (errors != 0)
        if (verbose)
            BIO_printf(bio_err, "User errors %d.\n", errors);

    if (verbose)
        BIO_printf(bio_err, "SRP terminating with code %d.\n", ret);
    OPENSSL_free(tofree);
    if (ret)
        ERR_print_errors(bio_err);
    if (randfile)
        app_RAND_write_file(randfile);
    NCONF_free(conf);
    free_index(db);
    OBJ_cleanup();
    return (ret);
}
Exemple #17
0
static void oid_module_finish(CONF_IMODULE *md)
{
    OBJ_cleanup();
}
int MAIN(int argc, char **argv)
	{
	ENGINE *e = NULL;
	int ret=1;
	X509_REQ *req=NULL;
	X509 *x=NULL,*xca=NULL;
	ASN1_OBJECT *objtmp;
	STACK_OF(OPENSSL_STRING) *sigopts = NULL;
	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;
#ifndef OPENSSL_NO_MD5
	int subject_hash_old=0,issuer_hash_old=0;
#endif
	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=NULL;
	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(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,"-sigopt") == 0)
			{
			if (--argc < 1)
				goto bad;
			if (!sigopts)
				sigopts = sk_OPENSSL_STRING_new_null();
			if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, *(++argv)))
				goto bad;
			}
		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;
#ifndef OPENSSL_NO_MD5
		else if (strcmp(*argv,"-subject_hash_old") == 0)
			subject_hash_old= ++num;
#endif
		else if (strcmp(*argv,"-issuer_hash") == 0)
			issuer_hash= ++num;
#ifndef OPENSSL_NO_MD5
		else if (strcmp(*argv,"-issuer_hash_old") == 0)
			issuer_hash_old= ++num;
#endif
		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_time_adj_ex(X509_get_notAfter(x),days, 0, NULL);

		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_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(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];
				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);
	}
Exemple #19
0
int MAIN(int argc, char **argv)
{
    int i, badops = 0, offset = 0, ret = 1, j;
    unsigned int length = 0;
    long num, tmplen;
    BIO *in = NULL, *out = NULL, *b64 = NULL, *derout = NULL;
    int informat, indent = 0, noout = 0, dump = 0, strictpem = 0;
    char *infile = NULL, *str = NULL, *prog, *oidfile = NULL, *derfile =
        NULL, *name = NULL, *header = NULL;
    char *genstr = NULL, *genconf = NULL;
    unsigned char *tmpbuf;
    const unsigned char *ctmpbuf;
    BUF_MEM *buf = NULL;
    STACK_OF(OPENSSL_STRING) *osk = NULL;
    ASN1_TYPE *at = NULL;

    informat = FORMAT_PEM;

    apps_startup();

    if (bio_err == NULL)
        if ((bio_err = BIO_new(BIO_s_file())) != NULL)
            BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT);

    if (!load_config(bio_err, NULL))
        goto end;

    prog = argv[0];
    argc--;
    argv++;
    if ((osk = sk_OPENSSL_STRING_new_null()) == NULL) {
        BIO_printf(bio_err, "Memory allocation failure\n");
        goto end;
    }
    while (argc >= 1) {
        if (strcmp(*argv, "-inform") == 0) {
            if (--argc < 1)
                goto bad;
            informat = str2fmt(*(++argv));
        } else if (strcmp(*argv, "-in") == 0) {
            if (--argc < 1)
                goto bad;
            infile = *(++argv);
        } else if (strcmp(*argv, "-out") == 0) {
            if (--argc < 1)
                goto bad;
            derfile = *(++argv);
        } else if (strcmp(*argv, "-i") == 0) {
            indent = 1;
        } else if (strcmp(*argv, "-noout") == 0)
            noout = 1;
        else if (strcmp(*argv, "-oid") == 0) {
            if (--argc < 1)
                goto bad;
            oidfile = *(++argv);
        } else if (strcmp(*argv, "-offset") == 0) {
            if (--argc < 1)
                goto bad;
            offset = atoi(*(++argv));
        } else if (strcmp(*argv, "-length") == 0) {
            if (--argc < 1)
                goto bad;
            length = atoi(*(++argv));
            if (length == 0)
                goto bad;
        } else if (strcmp(*argv, "-dump") == 0) {
            dump = -1;
        } else if (strcmp(*argv, "-dlimit") == 0) {
            if (--argc < 1)
                goto bad;
            dump = atoi(*(++argv));
            if (dump <= 0)
                goto bad;
        } else if (strcmp(*argv, "-strparse") == 0) {
            if (--argc < 1)
                goto bad;
            sk_OPENSSL_STRING_push(osk, *(++argv));
        } else if (strcmp(*argv, "-genstr") == 0) {
            if (--argc < 1)
                goto bad;
            genstr = *(++argv);
        } else if (strcmp(*argv, "-genconf") == 0) {
            if (--argc < 1)
                goto bad;
            genconf = *(++argv);
        } else if (strcmp(*argv, "-strictpem") == 0) {
            strictpem = 1;
            informat = FORMAT_PEM;
        } else {
            BIO_printf(bio_err, "unknown option %s\n", *argv);
            badops = 1;
            break;
        }
        argc--;
        argv++;
    }

    if (badops) {
 bad:
        BIO_printf(bio_err, "%s [options] <infile\n", prog);
        BIO_printf(bio_err, "where options are\n");
        BIO_printf(bio_err, " -inform arg   input format - one of DER PEM\n");
        BIO_printf(bio_err, " -in arg       input file\n");
        BIO_printf(bio_err,
                   " -out arg      output file (output format is always DER\n");
        BIO_printf(bio_err, " -noout arg    don't produce any output\n");
        BIO_printf(bio_err, " -offset arg   offset into file\n");
        BIO_printf(bio_err, " -length arg   length of section in file\n");
        BIO_printf(bio_err, " -i            indent entries\n");
        BIO_printf(bio_err, " -dump         dump unknown data in hex form\n");
        BIO_printf(bio_err,
                   " -dlimit arg   dump the first arg bytes of unknown data in hex form\n");
        BIO_printf(bio_err, " -oid file     file of extra oid definitions\n");
        BIO_printf(bio_err, " -strparse offset\n");
        BIO_printf(bio_err,
                   "               a series of these can be used to 'dig' into multiple\n");
        BIO_printf(bio_err, "               ASN1 blob wrappings\n");
        BIO_printf(bio_err,
                   " -genstr str   string to generate ASN1 structure from\n");
        BIO_printf(bio_err,
                   " -genconf file file to generate ASN1 structure from\n");
        BIO_printf(bio_err,
                   " -strictpem    do not attempt base64 decode outside PEM markers (-inform \n");
        BIO_printf(bio_err, "               will be ignored)\n");
        goto end;
    }

    ERR_load_crypto_strings();

    in = BIO_new(BIO_s_file());
    out = BIO_new(BIO_s_file());
    if ((in == NULL) || (out == NULL)) {
        ERR_print_errors(bio_err);
        goto end;
    }
    BIO_set_fp(out, stdout, BIO_NOCLOSE | BIO_FP_TEXT);
#ifdef OPENSSL_SYS_VMS
    {
        BIO *tmpbio = BIO_new(BIO_f_linebuffer());
        out = BIO_push(tmpbio, out);
    }
#endif

    if (oidfile != NULL) {
        if (BIO_read_filename(in, oidfile) <= 0) {
            BIO_printf(bio_err, "problems opening %s\n", oidfile);
            ERR_print_errors(bio_err);
            goto end;
        }
        OBJ_create_objects(in);
    }

    if (infile == NULL)
        BIO_set_fp(in, stdin, BIO_NOCLOSE);
    else {
        if (BIO_read_filename(in, infile) <= 0) {
            perror(infile);
            goto end;
        }
    }

    if (derfile) {
        if (!(derout = BIO_new_file(derfile, "wb"))) {
            BIO_printf(bio_err, "problems opening %s\n", derfile);
            ERR_print_errors(bio_err);
            goto end;
        }
    }

    if (strictpem) {
        if (PEM_read_bio(in, &name, &header, (unsigned char **)&str, &num) !=
            1) {
            BIO_printf(bio_err, "Error reading PEM file\n");
            ERR_print_errors(bio_err);
            goto end;
        }
    } else {

        if ((buf = BUF_MEM_new()) == NULL)
            goto end;
        if (!BUF_MEM_grow(buf, BUFSIZ * 8))
            goto end;           /* Pre-allocate :-) */

        if (genstr || genconf) {
            num = do_generate(bio_err, genstr, genconf, buf);
            if (num < 0) {
                ERR_print_errors(bio_err);
                goto end;
            }
        }

        else {

            if (informat == FORMAT_PEM) {
                BIO *tmp;

                if ((b64 = BIO_new(BIO_f_base64())) == NULL)
                    goto end;
                BIO_push(b64, in);
                tmp = in;
                in = b64;
                b64 = tmp;
            }

            num = 0;
            for (;;) {
                if (!BUF_MEM_grow(buf, (int)num + BUFSIZ))
                    goto end;
                i = BIO_read(in, &(buf->data[num]), BUFSIZ);
                if (i <= 0)
                    break;
                num += i;
            }
        }
        str = buf->data;

    }

    /* If any structs to parse go through in sequence */

    if (sk_OPENSSL_STRING_num(osk)) {
        tmpbuf = (unsigned char *)str;
        tmplen = num;
        for (i = 0; i < sk_OPENSSL_STRING_num(osk); i++) {
            ASN1_TYPE *atmp;
            int typ;
            j = atoi(sk_OPENSSL_STRING_value(osk, i));
            if (j == 0) {
                BIO_printf(bio_err, "'%s' is an invalid number\n",
                           sk_OPENSSL_STRING_value(osk, i));
                continue;
            }
            tmpbuf += j;
            tmplen -= j;
            atmp = at;
            ctmpbuf = tmpbuf;
            at = d2i_ASN1_TYPE(NULL, &ctmpbuf, tmplen);
            ASN1_TYPE_free(atmp);
            if (!at) {
                BIO_printf(bio_err, "Error parsing structure\n");
                ERR_print_errors(bio_err);
                goto end;
            }
            typ = ASN1_TYPE_get(at);
            if ((typ == V_ASN1_OBJECT)
                || (typ == V_ASN1_NULL)) {
                BIO_printf(bio_err, "Can't parse %s type\n",
                           typ == V_ASN1_NULL ? "NULL" : "OBJECT");
                ERR_print_errors(bio_err);
                goto end;
            }
            /* hmm... this is a little evil but it works */
            tmpbuf = at->value.asn1_string->data;
            tmplen = at->value.asn1_string->length;
        }
        str = (char *)tmpbuf;
        num = tmplen;
    }

    if (offset >= num) {
        BIO_printf(bio_err, "Error: offset too large\n");
        goto end;
    }

    num -= offset;

    if ((length == 0) || ((long)length > num))
        length = (unsigned int)num;
    if (derout) {
        if (BIO_write(derout, str + offset, length) != (int)length) {
            BIO_printf(bio_err, "Error writing output\n");
            ERR_print_errors(bio_err);
            goto end;
        }
    }
    if (!noout &&
        !ASN1_parse_dump(out, (unsigned char *)&(str[offset]), length,
                         indent, dump)) {
        ERR_print_errors(bio_err);
        goto end;
    }
    ret = 0;
 end:
    BIO_free(derout);
    BIO_free(in);
    BIO_free_all(out);
    BIO_free(b64);
    if (ret != 0)
        ERR_print_errors(bio_err);
    if (buf != NULL)
        BUF_MEM_free(buf);
    if (name != NULL)
        OPENSSL_free(name);
    if (header != NULL)
        OPENSSL_free(header);
    if (strictpem && str != NULL)
        OPENSSL_free(str);
    if (at != NULL)
        ASN1_TYPE_free(at);
    if (osk != NULL)
        sk_OPENSSL_STRING_free(osk);
    OBJ_cleanup();
    apps_shutdown();
    OPENSSL_EXIT(ret);
}
Exemple #20
0
int ts_main(int argc, char **argv)
{
    CONF *conf = NULL;
    char *CAfile = NULL, *untrusted = NULL, *engine = NULL, *prog, **helpp;
    char *configfile = NULL, *section = NULL, *password = NULL;
    char *data = NULL, *digest = NULL, *rnd = NULL, *policy = NULL;
    char *in = NULL, *out = NULL, *queryfile = NULL, *passin = NULL;
    char *inkey = NULL, *signer = NULL, *chain = NULL, *CApath = NULL;
    const EVP_MD *md = NULL;
    OPTION_CHOICE o, mode = OPT_ERR;
    int ret = 1, no_nonce = 0, cert = 0, text = 0;
    /* Input is ContentInfo instead of TimeStampResp. */
    int token_in = 0;
    /* Output is ContentInfo instead of TimeStampResp. */
    int token_out = 0;

    prog = opt_init(argc, argv, ts_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(ts_options);
            for (helpp = opt_helplist; *helpp; ++helpp)
                BIO_printf(bio_err, "%s\n", *helpp);
            ret = 0;
            goto end;
        case OPT_CONFIG:
            configfile = opt_arg();
            break;
        case OPT_SECTION:
            section = opt_arg();
            break;
        case OPT_QUERY:
        case OPT_REPLY:
        case OPT_VERIFY:
            if (mode != OPT_ERR)
                goto opthelp;
            mode = o;
            break;
        case OPT_DATA:
            data = opt_arg();
            break;
        case OPT_DIGEST:
            digest = opt_arg();
            break;
        case OPT_RAND:
            rnd = opt_arg();
            break;
        case OPT_POLICY:
            policy = opt_arg();
            break;
        case OPT_NO_NONCE:
            no_nonce = 1;
            break;
        case OPT_CERT:
            cert = 1;
            break;
        case OPT_IN:
            in = opt_arg();
            break;
        case OPT_TOKEN_IN:
            token_in = 1;
            break;
        case OPT_OUT:
            out = opt_arg();
            break;
        case OPT_TOKEN_OUT:
            token_out = 1;
            break;
        case OPT_TEXT:
            text = 1;
            break;
        case OPT_QUERYFILE:
            queryfile = opt_arg();
            break;
        case OPT_PASSIN:
            passin = opt_arg();
            break;
        case OPT_INKEY:
            inkey = opt_arg();
            break;
        case OPT_SIGNER:
            signer = opt_arg();
            break;
        case OPT_CHAIN:
            chain = opt_arg();
            break;
        case OPT_CAPATH:
            CApath = opt_arg();
            break;
        case OPT_CAFILE:
            CAfile = opt_arg();
            break;
        case OPT_UNTRUSTED:
            untrusted = opt_arg();
            break;
        case OPT_ENGINE:
            engine = opt_arg();
            break;
        case OPT_MD:
            if (!opt_md(opt_unknown(), &md))
                goto opthelp;
            break;
        }
    }
    argc = opt_num_rest();
    argv = opt_rest();
    if (mode == OPT_ERR || argc != 0)
        goto opthelp;

    /* Seed the random number generator if it is going to be used. */
    if (mode == OPT_QUERY && !no_nonce) {
        if (!app_RAND_load_file(NULL, 1) && rnd == NULL)
            BIO_printf(bio_err, "warning, not much extra random "
                       "data, consider using the -rand option\n");
        if (rnd != NULL)
            BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
                       app_RAND_load_files(rnd));
    }

    /* Get the password if required. */
    if (mode == OPT_REPLY && passin &&
        !app_passwd(passin, NULL, &password, NULL)) {
        BIO_printf(bio_err, "Error getting password.\n");
        goto end;
    }

    /*
     * Check consistency of parameters and execute the appropriate function.
     */
    switch (mode) {
    default:
    case OPT_ERR:
        goto opthelp;
    case OPT_QUERY:
        /*
         * Data file and message imprint cannot be specified at the same
         * time.
         */
        ret = data != NULL && digest != NULL;
        if (ret)
            goto opthelp;
        /* Load the config file for possible policy OIDs. */
        conf = load_config_file(configfile);
        ret = !query_command(data, digest, md, policy, no_nonce, cert,
                             in, out, text);
        break;
    case OPT_REPLY:
        conf = load_config_file(configfile);
        if (in == NULL) {
            ret = !(queryfile != NULL && conf != NULL && !token_in);
            if (ret)
                goto opthelp;
        } else {
            /* 'in' and 'queryfile' are exclusive. */
            ret = !(queryfile == NULL);
            if (ret)
                goto opthelp;
        }
        ret = !reply_command(conf, section, engine, queryfile,
                             password, inkey, signer, chain, policy,
                             in, token_in, out, token_out, text);
        break;
    case OPT_VERIFY:
        ret = !(((queryfile && !data && !digest)
                 || (!queryfile && data && !digest)
                 || (!queryfile && !data && digest))
                && in != NULL);
        if (ret)
            goto opthelp;

        ret = !verify_command(data, digest, queryfile, in, token_in,
                              CApath, CAfile, untrusted);
    }

 end:
    /* Clean up. */
    app_RAND_write_file(NULL);
    NCONF_free(conf);
    OPENSSL_free(password);
    OBJ_cleanup();

    return (ret);
}
// when not needed anymore
static void _commitmentExt_end() {
	OBJ_cleanup();
}
Exemple #22
0
int MAIN(int argc, char **argv)
	{
	int add_user = 0;
	int list_user= 0;
	int delete_user= 0;
	int modify_user= 0;
	char * user = NULL;

	char *passargin = NULL, *passargout = NULL;
	char *passin = NULL, *passout = NULL;
        char * gN = NULL;
	int gNindex = -1;
	char ** gNrow = NULL;
	int maxgN = -1;

	char * userinfo = NULL;

	int badops=0;
	int ret=1;
	int errors=0;
	int verbose=0;
	int doupdatedb=0;
	char *configfile=NULL;
	char *dbfile=NULL;
	CA_DB *db=NULL;
	char **pp ;
	int i;
	long errorline = -1;
	char *randfile=NULL;
#ifndef OPENSSL_NO_ENGINE
	char *engine = NULL;
#endif
	char *tofree=NULL;
	DB_ATTR db_attr;

#ifdef EFENCE
EF_PROTECT_FREE=1;
EF_PROTECT_BELOW=1;
EF_ALIGNMENT=0;
#endif

	apps_startup();

	conf = NULL;
	section = NULL;

	if (bio_err == NULL)
		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);

	argc--;
	argv++;
	while (argc >= 1 && badops == 0)
		{
		if	(strcmp(*argv,"-verbose") == 0)
			verbose++;
		else if	(strcmp(*argv,"-config") == 0)
			{
			if (--argc < 1) goto bad;
			configfile= *(++argv);
			}
		else if (strcmp(*argv,"-name") == 0)
			{
			if (--argc < 1) goto bad;
			section= *(++argv);
			}
		else if	(strcmp(*argv,"-srpvfile") == 0)
			{
			if (--argc < 1) goto bad;
			dbfile= *(++argv);
			}
		else if (strcmp(*argv,"-add") == 0)
			add_user=1;
		else if (strcmp(*argv,"-delete") == 0)
			delete_user=1;
		else if (strcmp(*argv,"-modify") == 0)
			modify_user=1;
		else if (strcmp(*argv,"-list") == 0)
			list_user=1;
		else if (strcmp(*argv,"-gn") == 0)
			{
			if (--argc < 1) goto bad;
			gN= *(++argv);
			}
		else if (strcmp(*argv,"-userinfo") == 0)
			{
			if (--argc < 1) goto bad;
			userinfo= *(++argv);
			}
		else if (strcmp(*argv,"-passin") == 0)
			{
			if (--argc < 1) goto bad;
			passargin= *(++argv);
			}
		else if (strcmp(*argv,"-passout") == 0)
			{
			if (--argc < 1) goto bad;
			passargout= *(++argv);
			}
#ifndef OPENSSL_NO_ENGINE
		else if (strcmp(*argv,"-engine") == 0)
			{
			if (--argc < 1) goto bad;
			engine= *(++argv);
			}
#endif

		else if (**argv == '-')
			{
bad:
			BIO_printf(bio_err,"unknown option %s\n",*argv);
			badops=1;
			break;
			}
		else 
			break;
	
		argc--;
		argv++;
		}

	if (dbfile && configfile)
		{
		BIO_printf(bio_err,"-dbfile and -configfile cannot be specified together.\n");
		badops = 1;
		}
	if (add_user+delete_user+modify_user+list_user != 1)
		{
		BIO_printf(bio_err,"Exactly one of the options -add, -delete, -modify -list must be specified.\n");
		badops = 1;
		}
	if (delete_user+modify_user+delete_user== 1 && argc <= 0)
		{
		BIO_printf(bio_err,"Need at least one user for options -add, -delete, -modify. \n");
		badops = 1;
		}
	if ((passin || passout) && argc != 1 )
		{
		BIO_printf(bio_err,"-passin, -passout arguments only valid with one user.\n");
		badops = 1;
		}

	if (badops)
		{
		for (pp=srp_usage; (*pp != NULL); pp++)
			BIO_printf(bio_err,"%s",*pp);

		BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
		BIO_printf(bio_err,"                 load the file (or the files in the directory) into\n");
		BIO_printf(bio_err,"                 the random number generator\n");
		goto err;
		}

	ERR_load_crypto_strings();

#ifndef OPENSSL_NO_ENGINE
	setup_engine(bio_err, engine, 0);
#endif

	if(!app_passwd(bio_err, passargin, passargout, &passin, &passout))
		{
		BIO_printf(bio_err, "Error getting passwords\n");
		goto err;
		}

        if (!dbfile)
		{


	/*****************************************************************/
		tofree=NULL;
		if (configfile == NULL) configfile = getenv("OPENSSL_CONF");
		if (configfile == NULL) configfile = getenv("SSLEAY_CONF");
		if (configfile == NULL)
			{
			const char *s=X509_get_default_cert_area();
			size_t len;

#ifdef OPENSSL_SYS_VMS
			len = strlen(s)+sizeof(CONFIG_FILE);
			tofree=OPENSSL_malloc(len);
			strcpy(tofree,s);
#else
			len = strlen(s)+sizeof(CONFIG_FILE)+1;
			tofree=OPENSSL_malloc(len);
			BUF_strlcpy(tofree,s,len);
			BUF_strlcat(tofree,"/",len);
#endif
			BUF_strlcat(tofree,CONFIG_FILE,len);
			configfile=tofree;
			}

		VERBOSE BIO_printf(bio_err,"Using configuration from %s\n",configfile);
		conf = NCONF_new(NULL);
		if (NCONF_load(conf,configfile,&errorline) <= 0)
			{
			if (errorline <= 0)
				BIO_printf(bio_err,"error loading the config file '%s'\n",
					configfile);
			else
				BIO_printf(bio_err,"error on line %ld of config file '%s'\n"
					,errorline,configfile);
			goto err;
			}
		if(tofree)
			{
			OPENSSL_free(tofree);
			tofree = NULL;
			}

		if (!load_config(bio_err, conf))
			goto err;

	/* Lets get the config section we are using */
		if (section == NULL)
			{
			VERBOSE BIO_printf(bio_err,"trying to read " ENV_DEFAULT_SRP " in \" BASE_SECTION \"\n");

			section=NCONF_get_string(conf,BASE_SECTION,ENV_DEFAULT_SRP);
			if (section == NULL)
				{
				lookup_fail(BASE_SECTION,ENV_DEFAULT_SRP);
				goto err;
				}
			}
         
		if (randfile == NULL && conf)
	        	randfile = NCONF_get_string(conf, BASE_SECTION, "RANDFILE");

	
		VERBOSE BIO_printf(bio_err,"trying to read " ENV_DATABASE " in section \"%s\"\n",section);

		if ((dbfile=NCONF_get_string(conf,section,ENV_DATABASE)) == NULL)
			{
			lookup_fail(section,ENV_DATABASE);
			goto err;
			}

        	}
	if (randfile == NULL)
		ERR_clear_error();
       	else 
		app_RAND_load_file(randfile, bio_err, 0);

	VERBOSE BIO_printf(bio_err,"Trying to read SRP verifier file \"%s\"\n",dbfile);

	db = load_index(dbfile, &db_attr);
	if (db == NULL) goto err;

	/* Lets check some fields */
	for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++)
		{
		pp = sk_OPENSSL_PSTRING_value(db->db->data, i);
	
		if (pp[DB_srptype][0] == DB_SRP_INDEX)
			{
			maxgN = i;
			if (gNindex < 0 && gN != NULL && !strcmp(gN, pp[DB_srpid]))
				gNindex = i;

			print_index(db, bio_err, i, verbose > 1);
			}
		}
	
	VERBOSE BIO_printf(bio_err, "Database initialised\n");

	if (gNindex >= 0)
		{
		gNrow = sk_OPENSSL_PSTRING_value(db->db->data,gNindex);
		print_entry(db, bio_err, gNindex, verbose > 1, "Default g and N");
		}
	else if (maxgN > 0 && !SRP_get_default_gN(gN))
		{
		BIO_printf(bio_err, "No g and N value for index \"%s\"\n", gN);
		goto err;
		}
	else
		{
		VERBOSE BIO_printf(bio_err, "Database has no g N information.\n");
		gNrow = NULL;
		}
	

	VVERBOSE BIO_printf(bio_err,"Starting user processing\n");

	if (argc > 0)
		user = *(argv++) ;

	while (list_user || user)
		{
		int userindex = -1;
		if (user) 
			VVERBOSE BIO_printf(bio_err, "Processing user \"%s\"\n", user);
		if ((userindex = get_index(db, user, 'U')) >= 0)
			{
			print_user(db, bio_err, userindex, (verbose > 0) || list_user);
			}
		
		if (list_user)
			{
			if (user == NULL)
				{
				BIO_printf(bio_err,"List all users\n");

				for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++)
					{
					print_user(db,bio_err, i, 1);
					}
				list_user = 0;
				}
			else if (userindex < 0)
				{
				BIO_printf(bio_err, "user \"%s\" does not exist, ignored. t\n",
					   user);
				errors++;
				}
			}
		else if (add_user)
			{
			if (userindex >= 0)
				{
				/* reactivation of a new user */
				char **row = sk_OPENSSL_PSTRING_value(db->db->data, userindex);
				BIO_printf(bio_err, "user \"%s\" reactivated.\n", user);
				row[DB_srptype][0] = 'V';

				doupdatedb = 1;
				}
			else
				{
				char *row[DB_NUMBER] ; char *gNid;
				row[DB_srpverifier] = NULL;
				row[DB_srpsalt] = NULL;
				row[DB_srpinfo] = NULL;
				if (!(gNid = srp_create_user(user,&(row[DB_srpverifier]), &(row[DB_srpsalt]),gNrow?gNrow[DB_srpsalt]:gN,gNrow?gNrow[DB_srpverifier]:NULL, passout, bio_err,verbose)))
					{
						BIO_printf(bio_err, "Cannot create srp verifier for user \"%s\", operation abandoned .\n", user);
						errors++;
						goto err;
					}
				row[DB_srpid] = BUF_strdup(user);
				row[DB_srptype] = BUF_strdup("v");
				row[DB_srpgN] = BUF_strdup(gNid);

				if (!row[DB_srpid] || !row[DB_srpgN] || !row[DB_srptype] || !row[DB_srpverifier] || !row[DB_srpsalt] ||
					(userinfo && (!(row[DB_srpinfo] = BUF_strdup(userinfo)))) || 
					!update_index(db, bio_err, row))
					{
					if (row[DB_srpid]) OPENSSL_free(row[DB_srpid]);
					if (row[DB_srpgN]) OPENSSL_free(row[DB_srpgN]);
					if (row[DB_srpinfo]) OPENSSL_free(row[DB_srpinfo]);
					if (row[DB_srptype]) OPENSSL_free(row[DB_srptype]);
					if (row[DB_srpverifier]) OPENSSL_free(row[DB_srpverifier]);
					if (row[DB_srpsalt]) OPENSSL_free(row[DB_srpsalt]);
					goto err;
					}
				doupdatedb = 1;
				}
			}
		else if (modify_user)
			{
			if (userindex < 0)
				{
				BIO_printf(bio_err,"user \"%s\" does not exist, operation ignored.\n",user);
				errors++;
				}
			else
				{

				char **row = sk_OPENSSL_PSTRING_value(db->db->data, userindex);
				char type = row[DB_srptype][0];
				if (type == 'v')
					{
					BIO_printf(bio_err,"user \"%s\" already updated, operation ignored.\n",user);
					errors++;
					}
				else
					{
					char *gNid;

					if (row[DB_srptype][0] == 'V')
						{
						int user_gN;
						char **irow = NULL;
						VERBOSE BIO_printf(bio_err,"Verifying password for user \"%s\"\n",user);
						if ( (user_gN = get_index(db, row[DB_srpgN], DB_SRP_INDEX)) >= 0)
							irow = (char **)sk_OPENSSL_PSTRING_value(db->db->data, userindex);

 						if (!srp_verify_user(user, row[DB_srpverifier], row[DB_srpsalt], irow ? irow[DB_srpsalt] : row[DB_srpgN], irow ? irow[DB_srpverifier] : NULL, passin, bio_err, verbose))
							{
							BIO_printf(bio_err, "Invalid password for user \"%s\", operation abandoned.\n", user);
							errors++;
							goto err;
							}
						} 
					VERBOSE BIO_printf(bio_err,"Password for user \"%s\" ok.\n",user);

					if (!(gNid=srp_create_user(user,&(row[DB_srpverifier]), &(row[DB_srpsalt]),gNrow?gNrow[DB_srpsalt]:NULL, gNrow?gNrow[DB_srpverifier]:NULL, passout, bio_err,verbose)))
						{
						BIO_printf(bio_err, "Cannot create srp verifier for user \"%s\", operation abandoned.\n", user);
						errors++;
						goto err;
						}

					row[DB_srptype][0] = 'v';
					row[DB_srpgN] = BUF_strdup(gNid);
 
					if (!row[DB_srpid] || !row[DB_srpgN] || !row[DB_srptype] || !row[DB_srpverifier] || !row[DB_srpsalt] ||
						(userinfo && (!(row[DB_srpinfo] = BUF_strdup(userinfo)))))  
						goto err;

					doupdatedb = 1;
					}
				}
			}
		else if (delete_user)
			{
			if (userindex < 0)
				{
				BIO_printf(bio_err, "user \"%s\" does not exist, operation ignored. t\n", user);
				errors++;
				}
			else
				{
				char **xpp = sk_OPENSSL_PSTRING_value(db->db->data,userindex);
				BIO_printf(bio_err, "user \"%s\" revoked. t\n", user);

				xpp[DB_srptype][0] = 'R';
				
				doupdatedb = 1;
				}
			}
		if (--argc > 0)
			user = *(argv++) ;
		else
			{
			user = NULL;
			list_user = 0;
			}
		}

	VERBOSE BIO_printf(bio_err,"User procession done.\n");


	if (doupdatedb)
		{
		/* Lets check some fields */
		for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++)
			{
			pp = sk_OPENSSL_PSTRING_value(db->db->data,i);
	
			if (pp[DB_srptype][0] == 'v')
				{
				pp[DB_srptype][0] = 'V';
				print_user(db, bio_err, i, verbose);
				}
			}

		VERBOSE BIO_printf(bio_err, "Trying to update srpvfile.\n");
		if (!save_index(dbfile, "new", db)) goto err;
				
		VERBOSE BIO_printf(bio_err, "Temporary srpvfile created.\n");
		if (!rotate_index(dbfile, "new", "old")) goto err;

		VERBOSE BIO_printf(bio_err, "srpvfile updated.\n");
		}

	ret = (errors != 0);
err:
	if (errors != 0)
	VERBOSE BIO_printf(bio_err,"User errors %d.\n",errors);

	VERBOSE BIO_printf(bio_err,"SRP terminating with code %d.\n",ret);
	if(tofree)
		OPENSSL_free(tofree);
	if (ret) ERR_print_errors(bio_err);
	if (randfile) app_RAND_write_file(randfile, bio_err);
	if (conf) NCONF_free(conf);
	if (db) free_index(db);

	OBJ_cleanup();
	apps_shutdown();
	OPENSSL_EXIT(ret);
	}
Exemple #23
0
int MAIN(int argc, char **argv)
	{
	int ret = 1;
	char *configfile = NULL;
	char *section = NULL;
	CONF *conf = NULL;
	enum mode {
	CMD_NONE, CMD_QUERY, CMD_REPLY, CMD_VERIFY 
	} mode = CMD_NONE;
	char *data = NULL;
	char *digest = NULL;
	const EVP_MD *md = NULL;
	char *rnd = NULL;
	char *policy = NULL;
	int no_nonce = 0;
	int cert = 0;
	char *in = NULL;
	char *out = NULL;
	int text = 0;
	char *queryfile = NULL;
	char *passin = NULL;	/* Password source. */
	char *password =NULL;	/* Password itself. */
	char *inkey = NULL;
	char *signer = NULL;
	char *chain = NULL;
	char *ca_path = NULL;
	char *ca_file = NULL;
	char *untrusted = NULL;
	char *engine = NULL;
	/* Input is ContentInfo instead of TimeStampResp. */
	int token_in = 0;	
	/* Output is ContentInfo instead of TimeStampResp. */
	int token_out = 0;
	int free_bio_err = 0;

	ERR_load_crypto_strings();
	apps_startup();

	if (bio_err == NULL && (bio_err = BIO_new(BIO_s_file())) != NULL)
		{
		free_bio_err = 1;
		BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT);
		}

	if (!load_config(bio_err, NULL))
		goto cleanup;

	for (argc--, argv++; argc > 0; argc--, argv++)
		{
		if (strcmp(*argv, "-config") == 0)
			{
			if (argc-- < 1) goto usage;
			configfile = *++argv;
			}
		else if (strcmp(*argv, "-section") == 0)
			{
			if (argc-- < 1) goto usage;
			section = *++argv;
			}
		else if (strcmp(*argv, "-query") == 0)
			{
			if (mode != CMD_NONE) goto usage;
			mode = CMD_QUERY;
			}
		else if (strcmp(*argv, "-data") == 0)
			{
			if (argc-- < 1) goto usage;
			data = *++argv;
			}
		else if (strcmp(*argv, "-digest") == 0)
			{
			if (argc-- < 1) goto usage;
			digest = *++argv;
			}
		else if (strcmp(*argv, "-rand") == 0)
			{
			if (argc-- < 1) goto usage;
			rnd = *++argv;
			}
		else if (strcmp(*argv, "-policy") == 0)
			{
			if (argc-- < 1) goto usage;
			policy = *++argv;
			}
		else if (strcmp(*argv, "-no_nonce") == 0)
			{
			no_nonce = 1;
			}
		else if (strcmp(*argv, "-cert") == 0)
			{
			cert = 1;
			}
		else if (strcmp(*argv, "-in") == 0)
			{
			if (argc-- < 1) goto usage;
			in = *++argv;
			}
		else if (strcmp(*argv, "-token_in") == 0)
			{
			token_in = 1;
			}
		else if (strcmp(*argv, "-out") == 0)
			{
			if (argc-- < 1) goto usage;
			out = *++argv;
			}
		else if (strcmp(*argv, "-token_out") == 0)
			{
			token_out = 1;
			}
		else if (strcmp(*argv, "-text") == 0)
			{
			text = 1;
			}
		else if (strcmp(*argv, "-reply") == 0)
			{
			if (mode != CMD_NONE) goto usage;
			mode = CMD_REPLY;
			}
		else if (strcmp(*argv, "-queryfile") == 0)
			{
			if (argc-- < 1) goto usage;
			queryfile = *++argv;
			}
		else if (strcmp(*argv, "-passin") == 0)
			{
			if (argc-- < 1) goto usage;
			passin = *++argv;
			}
		else if (strcmp(*argv, "-inkey") == 0)
			{
			if (argc-- < 1) goto usage;
			inkey = *++argv;
			}
		else if (strcmp(*argv, "-signer") == 0)
			{
			if (argc-- < 1) goto usage;
			signer = *++argv;
			}
		else if (strcmp(*argv, "-chain") == 0)
			{
			if (argc-- < 1) goto usage;
			chain = *++argv;
			}
		else if (strcmp(*argv, "-verify") == 0)
			{
			if (mode != CMD_NONE) goto usage;
			mode = CMD_VERIFY;
			}
		else if (strcmp(*argv, "-CApath") == 0)
			{
			if (argc-- < 1) goto usage;
			ca_path = *++argv;
			}
		else if (strcmp(*argv, "-CAfile") == 0)
			{
			if (argc-- < 1) goto usage;
			ca_file = *++argv;
			}
		else if (strcmp(*argv, "-untrusted") == 0)
			{
			if (argc-- < 1) goto usage;
			untrusted = *++argv;
			}
		else if (strcmp(*argv, "-engine") == 0)
			{
			if (argc-- < 1) goto usage;
			engine = *++argv;
			}
		else if ((md = EVP_get_digestbyname(*argv + 1)) != NULL)
			{
			/* empty. */
			}
		else
			goto usage;
		}
	
	/* Seed the random number generator if it is going to be used. */
	if (mode == CMD_QUERY && !no_nonce)
		{
		if (!app_RAND_load_file(NULL, bio_err, 1) && rnd == NULL)
			BIO_printf(bio_err, "warning, not much extra random "
				   "data, consider using the -rand option\n");
		if (rnd != NULL)
			BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
				   app_RAND_load_files(rnd));
		}

	/* Get the password if required. */
	if(mode == CMD_REPLY && passin &&
	   !app_passwd(bio_err, passin, NULL, &password, NULL))
		{
		BIO_printf(bio_err,"Error getting password.\n");
		goto cleanup;
		}

	/* Check consistency of parameters and execute 
	   the appropriate function. */
	switch (mode)
		{
	case CMD_NONE:
		goto usage;
	case CMD_QUERY:
		/* Data file and message imprint cannot be specified
		   at the same time. */
		ret = data != NULL && digest != NULL;
		if (ret) goto usage;
		/* Load the config file for possible policy OIDs. */
		conf = load_config_file(configfile);
		ret = !query_command(data, digest, md, policy, no_nonce, cert,
				     in, out, text);
		break;
	case CMD_REPLY:
		conf = load_config_file(configfile);
		if (in == NULL)
			{
			ret = !(queryfile != NULL && conf != NULL && !token_in);
			if (ret) goto usage;
			}
		else
			{
			/* 'in' and 'queryfile' are exclusive. */
			ret = !(queryfile == NULL);
			if (ret) goto usage;
			}

		ret = !reply_command(conf, section, engine, queryfile, 
				     password, inkey, signer, chain, policy, 
				     in, token_in, out, token_out, text);
		break;
	case CMD_VERIFY:
		ret = !(((queryfile && !data && !digest)
			 || (!queryfile && data && !digest)
			 || (!queryfile && !data && digest))
			&& in != NULL);
		if (ret) goto usage;

		ret = !verify_command(data, digest, queryfile, in, token_in,
				      ca_path, ca_file, untrusted);
		}

	goto cleanup;

 usage:
	BIO_printf(bio_err, "usage:\n"
		   "ts -query [-rand file%cfile%c...] [-config configfile] "
		   "[-data file_to_hash] [-digest digest_bytes]"
		   "[-md2|-md4|-md5|-sha|-sha1|-mdc2|-ripemd160] "
		   "[-policy object_id] [-no_nonce] [-cert] "
		   "[-in request.tsq] [-out request.tsq] [-text]\n",
		   LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
	BIO_printf(bio_err, "or\n"
		   "ts -reply [-config configfile] [-section tsa_section] "
		   "[-queryfile request.tsq] [-passin password] "
		   "[-signer tsa_cert.pem] [-inkey private_key.pem] "
		   "[-chain certs_file.pem] [-policy object_id] "
		   "[-in response.tsr] [-token_in] "
		   "[-out response.tsr] [-token_out] [-text] [-engine id]\n");
	BIO_printf(bio_err, "or\n"
		   "ts -verify [-data file_to_hash] [-digest digest_bytes] "
		   "[-queryfile request.tsq] "
		   "-in response.tsr [-token_in] "
		   "-CApath ca_path -CAfile ca_file.pem "
		   "-untrusted cert_file.pem\n");
 cleanup:
	/* Clean up. */
	app_RAND_write_file(NULL, bio_err);
	NCONF_free(conf);
	OPENSSL_free(password);
	OBJ_cleanup();
	if (free_bio_err)
		{
		BIO_free_all(bio_err);
		bio_err = NULL;
		}

	OPENSSL_EXIT(ret);
	}
Exemple #24
0
int MAIN(int argc, char **argv)
	{
	int i,badops=0,offset=0,ret=1,j;
	unsigned int length=0;
	long num,tmplen;
	BIO *in=NULL,*out=NULL,*b64=NULL, *derout = NULL;
	int informat,indent=0, noout = 0, dump = 0;
	char *infile=NULL,*str=NULL,*prog,*oidfile=NULL, *derfile=NULL;
	unsigned char *tmpbuf;
	BUF_MEM *buf=NULL;
	STACK *osk=NULL;
	ASN1_TYPE *at=NULL;

	informat=FORMAT_PEM;

	apps_startup();

	if (bio_err == NULL)
		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);

	prog=argv[0];
	argc--;
	argv++;
	if ((osk=sk_new_null()) == NULL)
		{
		BIO_printf(bio_err,"Memory allocation failure\n");
		goto end;
		}
	while (argc >= 1)
		{
		if 	(strcmp(*argv,"-inform") == 0)
			{
			if (--argc < 1) goto bad;
			informat=str2fmt(*(++argv));
			}
		else if (strcmp(*argv,"-in") == 0)
			{
			if (--argc < 1) goto bad;
			infile= *(++argv);
			}
		else if (strcmp(*argv,"-out") == 0)
			{
			if (--argc < 1) goto bad;
			derfile= *(++argv);
			}
		else if (strcmp(*argv,"-i") == 0)
			{
			indent=1;
			}
		else if (strcmp(*argv,"-noout") == 0) noout = 1;
		else if (strcmp(*argv,"-oid") == 0)
			{
			if (--argc < 1) goto bad;
			oidfile= *(++argv);
			}
		else if (strcmp(*argv,"-offset") == 0)
			{
			if (--argc < 1) goto bad;
			offset= atoi(*(++argv));
			}
		else if (strcmp(*argv,"-length") == 0)
			{
			if (--argc < 1) goto bad;
			length= atoi(*(++argv));
			if (length == 0) goto bad;
			}
		else if (strcmp(*argv,"-dump") == 0)
			{
			dump= -1;
			}
		else if (strcmp(*argv,"-dlimit") == 0)
			{
			if (--argc < 1) goto bad;
			dump= atoi(*(++argv));
			if (dump <= 0) goto bad;
			}
		else if (strcmp(*argv,"-strparse") == 0)
			{
			if (--argc < 1) goto bad;
			sk_push(osk,*(++argv));
			}
		else
			{
			BIO_printf(bio_err,"unknown option %s\n",*argv);
			badops=1;
			break;
			}
		argc--;
		argv++;
		}

	if (badops)
		{
bad:
		BIO_printf(bio_err,"%s [options] <infile\n",prog);
		BIO_printf(bio_err,"where options are\n");
		BIO_printf(bio_err," -inform arg   input format - one of DER TXT PEM\n");
		BIO_printf(bio_err," -in arg       input file\n");
		BIO_printf(bio_err," -out arg      output file (output format is always DER\n");
		BIO_printf(bio_err," -noout arg    don't produce any output\n");
		BIO_printf(bio_err," -offset arg   offset into file\n");
		BIO_printf(bio_err," -length arg   length of section in file\n");
		BIO_printf(bio_err," -i            indent entries\n");
		BIO_printf(bio_err," -dump         dump unknown data in hex form\n");
		BIO_printf(bio_err," -dlimit arg   dump the first arg bytes of unknown data in hex form\n");
		BIO_printf(bio_err," -oid file     file of extra oid definitions\n");
		BIO_printf(bio_err," -strparse offset\n");
		BIO_printf(bio_err,"               a series of these can be used to 'dig' into multiple\n");
		BIO_printf(bio_err,"               ASN1 blob wrappings\n");
		goto end;
		}

	ERR_load_crypto_strings();

	in=BIO_new(BIO_s_file());
	out=BIO_new(BIO_s_file());
	if ((in == NULL) || (out == NULL))
		{
		ERR_print_errors(bio_err);
		goto end;
		}
	BIO_set_fp(out,stdout,BIO_NOCLOSE|BIO_FP_TEXT);
#ifdef VMS
	{
	BIO *tmpbio = BIO_new(BIO_f_linebuffer());
	out = BIO_push(tmpbio, out);
	}
#endif

	if (oidfile != NULL)
		{
		if (BIO_read_filename(in,oidfile) <= 0)
			{
			BIO_printf(bio_err,"problems opening %s\n",oidfile);
			ERR_print_errors(bio_err);
			goto end;
			}
		OBJ_create_objects(in);
		}

	if (infile == NULL)
		BIO_set_fp(in,stdin,BIO_NOCLOSE);
	else
		{
		if (BIO_read_filename(in,infile) <= 0)
			{
			perror(infile);
			goto end;
			}
		}

	if (derfile) {
		if(!(derout = BIO_new_file(derfile, "wb"))) {
			BIO_printf(bio_err,"problems opening %s\n",derfile);
			ERR_print_errors(bio_err);
			goto end;
		}
	}

	if ((buf=BUF_MEM_new()) == NULL) goto end;
	if (!BUF_MEM_grow(buf,BUFSIZ*8)) goto end; /* Pre-allocate :-) */

	if (informat == FORMAT_PEM)
		{
		BIO *tmp;

		if ((b64=BIO_new(BIO_f_base64())) == NULL)
			goto end;
		BIO_push(b64,in);
		tmp=in;
		in=b64;
		b64=tmp;
		}

	num=0;
	for (;;)
		{
		if (!BUF_MEM_grow(buf,(int)num+BUFSIZ)) goto end;
		i=BIO_read(in,&(buf->data[num]),BUFSIZ);
		if (i <= 0) break;
		num+=i;
		}
	str=buf->data;

	/* If any structs to parse go through in sequence */

	if (sk_num(osk))
		{
		tmpbuf=(unsigned char *)str;
		tmplen=num;
		for (i=0; i<sk_num(osk); i++)
			{
			ASN1_TYPE *atmp;
			j=atoi(sk_value(osk,i));
			if (j == 0)
				{
				BIO_printf(bio_err,"'%s' is an invalid number\n",sk_value(osk,i));
				continue;
				}
			tmpbuf+=j;
			tmplen-=j;
			atmp = at;
			at = d2i_ASN1_TYPE(NULL,&tmpbuf,tmplen);
			ASN1_TYPE_free(atmp);
			if(!at)
				{
				BIO_printf(bio_err,"Error parsing structure\n");
				ERR_print_errors(bio_err);
				goto end;
				}
			/* hmm... this is a little evil but it works */
			tmpbuf=at->value.asn1_string->data;
			tmplen=at->value.asn1_string->length;
			}
		str=(char *)tmpbuf;
		num=tmplen;
		}

	if (length == 0) length=(unsigned int)num;
	if(derout) {
		if(BIO_write(derout, str + offset, length) != (int)length) {
			BIO_printf(bio_err, "Error writing output\n");
			ERR_print_errors(bio_err);
			goto end;
		}
	}
	if (!noout &&
	    !ASN1_parse_dump(out,(unsigned char *)&(str[offset]),length,
		    indent,dump))
		{
		ERR_print_errors(bio_err);
		goto end;
		}
	ret=0;
end:
	BIO_free(derout);
	if (in != NULL) BIO_free(in);
	if (out != NULL) BIO_free_all(out);
	if (b64 != NULL) BIO_free(b64);
	if (ret != 0)
		ERR_print_errors(bio_err);
	if (buf != NULL) BUF_MEM_free(buf);
	if (at != NULL) ASN1_TYPE_free(at);
	if (osk != NULL) sk_free(osk);
	OBJ_cleanup();
	OPENSSL_EXIT(ret);
	}
Exemple #25
0
int ts_main(int argc, char **argv)
{
    CONF *conf = NULL;
    char *CAfile = NULL, *untrusted = NULL, *engine = NULL, *prog, **helpp;
    char *configfile = default_config_file;
    char *section = NULL, *password = NULL;
    char *data = NULL, *digest = NULL, *rnd = NULL, *policy = NULL;
    char *in = NULL, *out = NULL, *queryfile = NULL, *passin = NULL;
    char *inkey = NULL, *signer = NULL, *chain = NULL, *CApath = NULL;
    const EVP_MD *md = NULL;
    OPTION_CHOICE o, mode = OPT_ERR;
    int ret = 1, no_nonce = 0, cert = 0, text = 0;
    int vpmtouched = 0;
    X509_VERIFY_PARAM *vpm = NULL;
    /* Input is ContentInfo instead of TimeStampResp. */
    int token_in = 0;
    /* Output is ContentInfo instead of TimeStampResp. */
    int token_out = 0;

    if ((vpm = X509_VERIFY_PARAM_new()) == NULL)
        goto end;

    prog = opt_init(argc, argv, ts_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(ts_options);
            for (helpp = opt_helplist; *helpp; ++helpp)
                BIO_printf(bio_err, "%s\n", *helpp);
            ret = 0;
            goto end;
        case OPT_CONFIG:
            configfile = opt_arg();
            break;
        case OPT_SECTION:
            section = opt_arg();
            break;
        case OPT_QUERY:
        case OPT_REPLY:
        case OPT_VERIFY:
            if (mode != OPT_ERR)
                goto opthelp;
            mode = o;
            break;
        case OPT_DATA:
            data = opt_arg();
            break;
        case OPT_DIGEST:
            digest = opt_arg();
            break;
        case OPT_RAND:
            rnd = opt_arg();
            break;
        case OPT_TSPOLICY:
            policy = opt_arg();
            break;
        case OPT_NO_NONCE:
            no_nonce = 1;
            break;
        case OPT_CERT:
            cert = 1;
            break;
        case OPT_IN:
            in = opt_arg();
            break;
        case OPT_TOKEN_IN:
            token_in = 1;
            break;
        case OPT_OUT:
            out = opt_arg();
            break;
        case OPT_TOKEN_OUT:
            token_out = 1;
            break;
        case OPT_TEXT:
            text = 1;
            break;
        case OPT_QUERYFILE:
            queryfile = opt_arg();
            break;
        case OPT_PASSIN:
            passin = opt_arg();
            break;
        case OPT_INKEY:
            inkey = opt_arg();
            break;
        case OPT_SIGNER:
            signer = opt_arg();
            break;
        case OPT_CHAIN:
            chain = opt_arg();
            break;
        case OPT_CAPATH:
            CApath = opt_arg();
            break;
        case OPT_CAFILE:
            CAfile = opt_arg();
            break;
        case OPT_UNTRUSTED:
            untrusted = opt_arg();
            break;
        case OPT_ENGINE:
            engine = opt_arg();
            break;
        case OPT_MD:
            if (!opt_md(opt_unknown(), &md))
                goto opthelp;
            break;
        case OPT_V_CASES:
            if (!opt_verify(o, vpm))
                goto end;
            vpmtouched++;
            break;
        }
    }
    argc = opt_num_rest();
    argv = opt_rest();
    if (mode == OPT_ERR || argc != 0)
        goto opthelp;

    /* Seed the random number generator if it is going to be used. */
    if (mode == OPT_QUERY && !no_nonce) {
        if (!app_RAND_load_file(NULL, 1) && rnd == NULL)
            BIO_printf(bio_err, "warning, not much extra random "
                       "data, consider using the -rand option\n");
        if (rnd != NULL)
            BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
                       app_RAND_load_files(rnd));
    }

    if (mode == OPT_REPLY && passin &&
        !app_passwd(passin, NULL, &password, NULL)) {
        BIO_printf(bio_err, "Error getting password.\n");
        goto end;
    }

    conf = load_config_file(configfile);
    if (!app_load_modules(conf))
        goto end;

    /* Check parameter consistency and execute the appropriate function. */
    switch (mode) {
    default:
    case OPT_ERR:
        goto opthelp;
    case OPT_QUERY:
        if (vpmtouched)
            goto opthelp;
        if ((data != NULL) && (digest != NULL))
            goto opthelp;
        ret = !query_command(data, digest, md, policy, no_nonce, cert,
                             in, out, text);
        break;
    case OPT_REPLY:
        if (vpmtouched)
            goto opthelp;
        if ((in != NULL) && (queryfile != NULL))
            goto opthelp;
        if (in == NULL) {
            if ((conf == NULL) || (token_in != 0))
                goto opthelp;
        }
        ret = !reply_command(conf, section, engine, queryfile,
                             password, inkey, md, signer, chain, policy,
                             in, token_in, out, token_out, text);
        break;
    case OPT_VERIFY:
        if ((in == NULL) || !EXACTLY_ONE(queryfile, data, digest))
            goto opthelp;
        ret = !verify_command(data, digest, queryfile, in, token_in,
                              CApath, CAfile, untrusted, 
                              vpmtouched ? vpm : NULL);
    }

 end:
    X509_VERIFY_PARAM_free(vpm);
    app_RAND_write_file(NULL);
    NCONF_free(conf);
    OPENSSL_free(password);
    OBJ_cleanup();
    return (ret);
}