Example #1
0
int ocsp_main(int argc, char **argv)
{
    BIO *acbio = NULL, *cbio = NULL, *derbio = NULL, *out = NULL;
    const EVP_MD *cert_id_md = NULL, *rsign_md = NULL;
    CA_DB *rdb = NULL;
    EVP_PKEY *key = NULL, *rkey = NULL;
    OCSP_BASICRESP *bs = NULL;
    OCSP_REQUEST *req = NULL;
    OCSP_RESPONSE *resp = NULL;
    STACK_OF(CONF_VALUE) *headers = NULL;
    STACK_OF(OCSP_CERTID) *ids = NULL;
    STACK_OF(OPENSSL_STRING) *reqnames = NULL;
    STACK_OF(X509) *sign_other = NULL, *verify_other = NULL, *rother = NULL;
    STACK_OF(X509) *issuers = NULL;
    X509 *issuer = NULL, *cert = NULL, *rca_cert = NULL;
    X509 *signer = NULL, *rsigner = NULL;
    X509_STORE *store = NULL;
    X509_VERIFY_PARAM *vpm = NULL;
    char *CAfile = NULL, *CApath = NULL, *header, *value;
    char *host = NULL, *port = NULL, *path = "/", *outfile = NULL;
    char *rca_filename = NULL, *reqin = NULL, *respin = NULL;
    char *reqout = NULL, *respout = NULL, *ridx_filename = NULL;
    char *rsignfile = NULL, *rkeyfile = NULL;
    char *sign_certfile = NULL, *verify_certfile = NULL, *rcertfile = NULL;
    char *signfile = NULL, *keyfile = NULL;
    char *thost = NULL, *tport = NULL, *tpath = NULL;
    int noCAfile = 0, noCApath = 0;
    int accept_count = -1, add_nonce = 1, noverify = 0, use_ssl = -1;
    int vpmtouched = 0, badsig = 0, i, ignore_err = 0, nmin = 0, ndays = -1;
    int req_text = 0, resp_text = 0, req_timeout = -1, ret = 1;
    long nsec = MAX_VALIDITY_PERIOD, maxage = -1;
    unsigned long sign_flags = 0, verify_flags = 0, rflags = 0;
    OPTION_CHOICE o;
    char *prog;

    reqnames = sk_OPENSSL_STRING_new_null();
    if (!reqnames)
        goto end;
    ids = sk_OCSP_CERTID_new_null();
    if (!ids)
        goto end;
    if ((vpm = X509_VERIFY_PARAM_new()) == NULL)
        return 1;

    prog = opt_init(argc, argv, ocsp_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:
            ret = 0;
            opt_help(ocsp_options);
            goto end;
        case OPT_OUTFILE:
            outfile = opt_arg();
            break;
        case OPT_TIMEOUT:
            req_timeout = atoi(opt_arg());
            break;
        case OPT_URL:
            OPENSSL_free(thost);
            OPENSSL_free(tport);
            OPENSSL_free(tpath);
            thost = tport = tpath = NULL;
            if (!OCSP_parse_url(opt_arg(), &host, &port, &path, &use_ssl)) {
                BIO_printf(bio_err, "%s Error parsing URL\n", prog);
                goto end;
            }
            thost = host;
            tport = port;
            tpath = path;
            break;
        case OPT_HOST:
            host = opt_arg();
            break;
        case OPT_PORT:
            port = opt_arg();
            break;
        case OPT_IGNORE_ERR:
            ignore_err = 1;
            break;
        case OPT_NOVERIFY:
            noverify = 1;
            break;
        case OPT_NONCE:
            add_nonce = 2;
            break;
        case OPT_NO_NONCE:
            add_nonce = 0;
            break;
        case OPT_RESP_NO_CERTS:
            rflags |= OCSP_NOCERTS;
            break;
        case OPT_RESP_KEY_ID:
            rflags |= OCSP_RESPID_KEY;
            break;
        case OPT_NO_CERTS:
            sign_flags |= OCSP_NOCERTS;
            break;
        case OPT_NO_SIGNATURE_VERIFY:
            verify_flags |= OCSP_NOSIGS;
            break;
        case OPT_NO_CERT_VERIFY:
            verify_flags |= OCSP_NOVERIFY;
            break;
        case OPT_NO_CHAIN:
            verify_flags |= OCSP_NOCHAIN;
            break;
        case OPT_NO_CERT_CHECKS:
            verify_flags |= OCSP_NOCHECKS;
            break;
        case OPT_NO_EXPLICIT:
            verify_flags |= OCSP_NOEXPLICIT;
            break;
        case OPT_TRUST_OTHER:
            verify_flags |= OCSP_TRUSTOTHER;
            break;
        case OPT_NO_INTERN:
            verify_flags |= OCSP_NOINTERN;
            break;
        case OPT_BADSIG:
            badsig = 1;
            break;
        case OPT_TEXT:
            req_text = resp_text = 1;
            break;
        case OPT_REQ_TEXT:
            req_text = 1;
            break;
        case OPT_RESP_TEXT:
            resp_text = 1;
            break;
        case OPT_REQIN:
            reqin = opt_arg();
            break;
        case OPT_RESPIN:
            respin = opt_arg();
            break;
        case OPT_SIGNER:
            signfile = opt_arg();
            break;
        case OPT_VAFILE:
            verify_certfile = opt_arg();
            verify_flags |= OCSP_TRUSTOTHER;
            break;
        case OPT_SIGN_OTHER:
            sign_certfile = opt_arg();
            break;
        case OPT_VERIFY_OTHER:
            verify_certfile = opt_arg();
            break;
        case OPT_CAFILE:
            CAfile = opt_arg();
            break;
        case OPT_CAPATH:
            CApath = opt_arg();
            break;
        case OPT_NOCAFILE:
            noCAfile = 1;
            break;
        case OPT_NOCAPATH:
            noCApath = 1;
            break;
        case OPT_V_CASES:
            if (!opt_verify(o, vpm))
                goto end;
            vpmtouched++;
            break;
        case OPT_VALIDITY_PERIOD:
            opt_long(opt_arg(), &nsec);
            break;
        case OPT_STATUS_AGE:
            opt_long(opt_arg(), &maxage);
            break;
        case OPT_SIGNKEY:
            keyfile = opt_arg();
            break;
        case OPT_REQOUT:
            reqout = opt_arg();
            break;
        case OPT_RESPOUT:
            respout = opt_arg();
            break;
        case OPT_PATH:
            path = opt_arg();
            break;
        case OPT_ISSUER:
            issuer = load_cert(opt_arg(), FORMAT_PEM, "issuer certificate");
            if (issuer == NULL)
                goto end;
            if (issuers == NULL) {
                if ((issuers = sk_X509_new_null()) == NULL)
                    goto end;
            }
            sk_X509_push(issuers, issuer);
            break;
        case OPT_CERT:
            X509_free(cert);
            cert = load_cert(opt_arg(), FORMAT_PEM, "certificate");
            if (cert == NULL)
                goto end;
            if (cert_id_md == NULL)
                cert_id_md = EVP_sha1();
            if (!add_ocsp_cert(&req, cert, cert_id_md, issuer, ids))
                goto end;
            if (!sk_OPENSSL_STRING_push(reqnames, opt_arg()))
                goto end;
            break;
        case OPT_SERIAL:
            if (cert_id_md == NULL)
                cert_id_md = EVP_sha1();
            if (!add_ocsp_serial(&req, opt_arg(), cert_id_md, issuer, ids))
                goto end;
            if (!sk_OPENSSL_STRING_push(reqnames, opt_arg()))
                goto end;
            break;
        case OPT_INDEX:
            ridx_filename = opt_arg();
            break;
        case OPT_CA:
            rca_filename = opt_arg();
            break;
        case OPT_NMIN:
            opt_int(opt_arg(), &nmin);
            if (ndays == -1)
                ndays = 0;
            break;
        case OPT_REQUEST:
            opt_int(opt_arg(), &accept_count);
            break;
        case OPT_NDAYS:
            ndays = atoi(opt_arg());
            break;
        case OPT_RSIGNER:
            rsignfile = opt_arg();
            break;
        case OPT_RKEY:
            rkeyfile = opt_arg();
            break;
        case OPT_ROTHER:
            rcertfile = opt_arg();
            break;
        case OPT_RMD:
            if (!opt_md(opt_arg(), &rsign_md))
                goto end;
            break;
        case OPT_HEADER:
            header = opt_arg();
            value = strchr(header, '=');
            if (value == NULL) {
                BIO_printf(bio_err, "Missing = in header key=value\n");
                goto opthelp;
            }
            *value++ = '\0';
            if (!X509V3_add_value(header, value, &headers))
                goto end;
            break;
        case OPT_MD:
            if (cert_id_md != NULL) {
                BIO_printf(bio_err,
                           "%s: Digest must be before -cert or -serial\n",
                           prog);
                goto opthelp;
            }
            if (!opt_md(opt_unknown(), &cert_id_md))
                goto opthelp;
            break;
        }
    }
    argc = opt_num_rest();
    if (argc != 0)
        goto opthelp;

    /* Have we anything to do? */
    if (!req && !reqin && !respin && !(port && ridx_filename))
        goto opthelp;

    out = bio_open_default(outfile, 'w', FORMAT_TEXT);
    if (out == NULL)
        goto end;

    if (!req && (add_nonce != 2))
        add_nonce = 0;

    if (!req && reqin) {
        derbio = bio_open_default(reqin, 'r', FORMAT_ASN1);
        if (derbio == NULL)
            goto end;
        req = d2i_OCSP_REQUEST_bio(derbio, NULL);
        BIO_free(derbio);
        if (!req) {
            BIO_printf(bio_err, "Error reading OCSP request\n");
            goto end;
        }
    }

    if (!req && port) {
        acbio = init_responder(port);
        if (!acbio)
            goto end;
    }

    if (rsignfile) {
        if (!rkeyfile)
            rkeyfile = rsignfile;
        rsigner = load_cert(rsignfile, FORMAT_PEM, "responder certificate");
        if (!rsigner) {
            BIO_printf(bio_err, "Error loading responder certificate\n");
            goto end;
        }
        rca_cert = load_cert(rca_filename, FORMAT_PEM, "CA certificate");
        if (rcertfile) {
            if (!load_certs(rcertfile, &rother, FORMAT_PEM, NULL,
                            "responder other certificates"))
                goto end;
        }
        rkey = load_key(rkeyfile, FORMAT_PEM, 0, NULL, NULL,
                        "responder private key");
        if (!rkey)
            goto end;
    }
    if (acbio)
        BIO_printf(bio_err, "Waiting for OCSP client connections...\n");

 redo_accept:

    if (acbio) {
        if (!do_responder(&req, &cbio, acbio))
            goto end;
        if (!req) {
            resp =
                OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST,
                                     NULL);
            send_ocsp_response(cbio, resp);
            goto done_resp;
        }
    }

    if (!req && (signfile || reqout || host || add_nonce || ridx_filename)) {
        BIO_printf(bio_err, "Need an OCSP request for this operation!\n");
        goto end;
    }

    if (req && add_nonce)
        OCSP_request_add1_nonce(req, NULL, -1);

    if (signfile) {
        if (!keyfile)
            keyfile = signfile;
        signer = load_cert(signfile, FORMAT_PEM, "signer certificate");
        if (!signer) {
            BIO_printf(bio_err, "Error loading signer certificate\n");
            goto end;
        }
        if (sign_certfile) {
            if (!load_certs(sign_certfile, &sign_other, FORMAT_PEM, NULL,
                            "signer certificates"))
                goto end;
        }
        key = load_key(keyfile, FORMAT_PEM, 0, NULL, NULL,
                       "signer private key");
        if (!key)
            goto end;

        if (!OCSP_request_sign
            (req, signer, key, NULL, sign_other, sign_flags)) {
            BIO_printf(bio_err, "Error signing OCSP request\n");
            goto end;
        }
    }

    if (req_text && req)
        OCSP_REQUEST_print(out, req, 0);

    if (reqout) {
        derbio = bio_open_default(reqout, 'w', FORMAT_ASN1);
        if (derbio == NULL)
            goto end;
        i2d_OCSP_REQUEST_bio(derbio, req);
        BIO_free(derbio);
    }

    if (ridx_filename && (!rkey || !rsigner || !rca_cert)) {
        BIO_printf(bio_err,
                   "Need a responder certificate, key and CA for this operation!\n");
        goto end;
    }

    if (ridx_filename && !rdb) {
        rdb = load_index(ridx_filename, NULL);
        if (!rdb)
            goto end;
        if (!index_index(rdb))
            goto end;
    }

    if (rdb) {
        make_ocsp_response(&resp, req, rdb, rca_cert, rsigner, rkey,
                               rsign_md, rother, rflags, nmin, ndays, badsig);
        if (cbio)
            send_ocsp_response(cbio, resp);
    } else if (host) {
# ifndef OPENSSL_NO_SOCK
        resp = process_responder(req, host, path,
                                 port, use_ssl, headers, req_timeout);
        if (!resp)
            goto end;
# else
        BIO_printf(bio_err,
                   "Error creating connect BIO - sockets not supported.\n");
        goto end;
# endif
    } else if (respin) {
        derbio = bio_open_default(respin, 'r', FORMAT_ASN1);
        if (derbio == NULL)
            goto end;
        resp = d2i_OCSP_RESPONSE_bio(derbio, NULL);
        BIO_free(derbio);
        if (!resp) {
            BIO_printf(bio_err, "Error reading OCSP response\n");
            goto end;
        }
    } else {
        ret = 0;
        goto end;
    }

 done_resp:

    if (respout) {
        derbio = bio_open_default(respout, 'w', FORMAT_ASN1);
        if (derbio == NULL)
            goto end;
        i2d_OCSP_RESPONSE_bio(derbio, resp);
        BIO_free(derbio);
    }

    i = OCSP_response_status(resp);
    if (i != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
        BIO_printf(out, "Responder Error: %s (%d)\n",
                   OCSP_response_status_str(i), i);
        if (ignore_err)
            goto redo_accept;
        ret = 0;
        goto end;
    }

    if (resp_text)
        OCSP_RESPONSE_print(out, resp, 0);

    /* If running as responder don't verify our own response */
    if (cbio) {
        /* If not unlimited, see if we took all we should. */
        if (accept_count != -1 && --accept_count <= 0) {
            ret = 0;
            goto end;
        }
        BIO_free_all(cbio);
        cbio = NULL;
        OCSP_REQUEST_free(req);
        req = NULL;
        OCSP_RESPONSE_free(resp);
        resp = NULL;
        goto redo_accept;
    }
    if (ridx_filename) {
        ret = 0;
        goto end;
    }

    if (!store) {
        store = setup_verify(CAfile, CApath, noCAfile, noCApath);
        if (!store)
            goto end;
    }
    if (vpmtouched)
        X509_STORE_set1_param(store, vpm);
    if (verify_certfile) {
        if (!load_certs(verify_certfile, &verify_other, FORMAT_PEM, NULL,
                        "validator certificate"))
            goto end;
    }

    bs = OCSP_response_get1_basic(resp);
    if (!bs) {
        BIO_printf(bio_err, "Error parsing response\n");
        goto end;
    }

    ret = 0;

    if (!noverify) {
        if (req && ((i = OCSP_check_nonce(req, bs)) <= 0)) {
            if (i == -1)
                BIO_printf(bio_err, "WARNING: no nonce in response\n");
            else {
                BIO_printf(bio_err, "Nonce Verify error\n");
                ret = 1;
                goto end;
            }
        }

        i = OCSP_basic_verify(bs, verify_other, store, verify_flags);
        if (i <= 0 && issuers) {
            i = OCSP_basic_verify(bs, issuers, store, OCSP_TRUSTOTHER);
            if (i > 0)
                ERR_clear_error();
        }
        if (i <= 0) {
            BIO_printf(bio_err, "Response Verify Failure\n");
            ERR_print_errors(bio_err);
            ret = 1;
        } else
            BIO_printf(bio_err, "Response verify OK\n");

    }

    print_ocsp_summary(out, bs, req, reqnames, ids, nsec, maxage);

 end:
    ERR_print_errors(bio_err);
    X509_free(signer);
    X509_STORE_free(store);
    X509_VERIFY_PARAM_free(vpm);
    EVP_PKEY_free(key);
    EVP_PKEY_free(rkey);
    X509_free(cert);
    sk_X509_pop_free(issuers, X509_free);
    X509_free(rsigner);
    X509_free(rca_cert);
    free_index(rdb);
    BIO_free_all(cbio);
    BIO_free_all(acbio);
    BIO_free(out);
    OCSP_REQUEST_free(req);
    OCSP_RESPONSE_free(resp);
    OCSP_BASICRESP_free(bs);
    sk_OPENSSL_STRING_free(reqnames);
    sk_OCSP_CERTID_free(ids);
    sk_X509_pop_free(sign_other, X509_free);
    sk_X509_pop_free(verify_other, X509_free);
    sk_CONF_VALUE_pop_free(headers, X509V3_conf_free);
    OPENSSL_free(thost);
    OPENSSL_free(tport);
    OPENSSL_free(tpath);

    return (ret);
}
Example #2
0
int MAIN(int argc, char **argv)
	{
	int ret=1,i;
	int verbose=0;
	char **pp;
	const char *p;
	int badops=0;
	SSL_CTX *ctx=NULL;
	SSL *ssl=NULL;
	char *ciphers=NULL;
	SSL_METHOD *meth=NULL;
	STACK_OF(SSL_CIPHER) *sk;
	char buf[512];
	BIO *STDout=NULL;

#if !defined(NO_SSL2) && !defined(NO_SSL3)
	meth=SSLv23_server_method();
#elif !defined(NO_SSL3)
	meth=SSLv3_server_method();
#elif !defined(NO_SSL2)
	meth=SSLv2_server_method();
#endif

	apps_startup();

	if (bio_err == NULL)
		bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
	STDout=BIO_new_fp(stdout,BIO_NOCLOSE);
#ifdef VMS
	{
	BIO *tmpbio = BIO_new(BIO_f_linebuffer());
	STDout = BIO_push(tmpbio, STDout);
	}
#endif

	argc--;
	argv++;
	while (argc >= 1)
		{
		if (strcmp(*argv,"-v") == 0)
			verbose=1;
#ifndef NO_SSL2
		else if (strcmp(*argv,"-ssl2") == 0)
			meth=SSLv2_client_method();
#endif
#ifndef NO_SSL3
		else if (strcmp(*argv,"-ssl3") == 0)
			meth=SSLv3_client_method();
#endif
#ifndef NO_TLS1
		else if (strcmp(*argv,"-tls1") == 0)
			meth=TLSv1_client_method();
#endif
		else if ((strncmp(*argv,"-h",2) == 0) ||
			 (strcmp(*argv,"-?") == 0))
			{
			badops=1;
			break;
			}
		else
			{
			ciphers= *argv;
			}
		argc--;
		argv++;
		}

	if (badops)
		{
		for (pp=ciphers_usage; (*pp != NULL); pp++)
			BIO_printf(bio_err,*pp);
		goto end;
		}

	OpenSSL_add_ssl_algorithms();

	ctx=SSL_CTX_new(meth);
	if (ctx == NULL) goto err;
	if (ciphers != NULL) {
		if(!SSL_CTX_set_cipher_list(ctx,ciphers)) {
			BIO_printf(bio_err, "Error in cipher list\n");
			goto err;
		}
	}
	ssl=SSL_new(ctx);
	if (ssl == NULL) goto err;


	if (!verbose)
		{
		for (i=0; ; i++)
			{
			p=SSL_get_cipher_list(ssl,i);
			if (p == NULL) break;
			if (i != 0) BIO_printf(STDout,":");
			BIO_printf(STDout,"%s",p);
			}
		BIO_printf(STDout,"\n");
		}
	else
		{
		sk=SSL_get_ciphers(ssl);

		for (i=0; i<sk_SSL_CIPHER_num(sk); i++)
			{
			BIO_puts(STDout,SSL_CIPHER_description(
				sk_SSL_CIPHER_value(sk,i),
				buf,512));
			}
		}

	ret=0;
	if (0)
		{
err:
		SSL_load_error_strings();
		ERR_print_errors(bio_err);
		}
end:
	if (ctx != NULL) SSL_CTX_free(ctx);
	if (ssl != NULL) SSL_free(ssl);
	if (STDout != NULL) BIO_free_all(STDout);
	EXIT(ret);
	}
Example #3
0
static int get_server_hello(SSL *s)
	{
	unsigned char *buf;
	unsigned char *p;
	int i,j;
	unsigned long len;
	STACK_OF(SSL_CIPHER) *sk=NULL,*cl, *prio, *allow;

	buf=(unsigned char *)s->init_buf->data;
	p=buf;
	if (s->state == SSL2_ST_GET_SERVER_HELLO_A)
		{
		i=ssl2_read(s,(char *)&(buf[s->init_num]),11-s->init_num);
		if (i < (11-s->init_num)) 
			return(ssl2_part_read(s,SSL_F_GET_SERVER_HELLO,i));
		s->init_num = 11;

		if (*(p++) != SSL2_MT_SERVER_HELLO)
			{
			if (p[-1] != SSL2_MT_ERROR)
				{
				ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
				SSLerr(SSL_F_GET_SERVER_HELLO,
					SSL_R_READ_WRONG_PACKET_TYPE);
				}
			else
				SSLerr(SSL_F_GET_SERVER_HELLO,
					SSL_R_PEER_ERROR);
			return(-1);
			}
#if 0
		s->hit=(*(p++))?1:0;
		/* Some [PPC?] compilers fail to increment p in above
		   statement, e.g. one provided with Rhapsody 5.5, but
		   most recent example XL C 11.1 for AIX, even without
		   optimization flag... */
#else
		s->hit=(*p)?1:0; p++;
#endif
		s->s2->tmp.cert_type= *(p++);
		n2s(p,i);
		if (i < s->version) s->version=i;
		n2s(p,i); s->s2->tmp.cert_length=i;
		n2s(p,i); s->s2->tmp.csl=i;
		n2s(p,i); s->s2->tmp.conn_id_length=i;
		s->state=SSL2_ST_GET_SERVER_HELLO_B;
		}

	/* SSL2_ST_GET_SERVER_HELLO_B */
	len = 11 + (unsigned long)s->s2->tmp.cert_length + (unsigned long)s->s2->tmp.csl + (unsigned long)s->s2->tmp.conn_id_length;
	if (len > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)
		{
		SSLerr(SSL_F_GET_SERVER_HELLO,SSL_R_MESSAGE_TOO_LONG);
		return -1;
		}
	j = (int)len - s->init_num;
	i = ssl2_read(s,(char *)&(buf[s->init_num]),j);
	if (i != j) return(ssl2_part_read(s,SSL_F_GET_SERVER_HELLO,i));
	if (s->msg_callback)
		s->msg_callback(0, s->version, 0, buf, (size_t)len, s, s->msg_callback_arg); /* SERVER-HELLO */

	/* things are looking good */

	p = buf + 11;
	if (s->hit)
		{
		if (s->s2->tmp.cert_length != 0) 
			{
			SSLerr(SSL_F_GET_SERVER_HELLO,SSL_R_REUSE_CERT_LENGTH_NOT_ZERO);
			return(-1);
			}
		if (s->s2->tmp.cert_type != 0)
			{
			if (!(s->options &
				SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG))
				{
				SSLerr(SSL_F_GET_SERVER_HELLO,SSL_R_REUSE_CERT_TYPE_NOT_ZERO);
				return(-1);
				}
			}
		if (s->s2->tmp.csl != 0)
			{
			SSLerr(SSL_F_GET_SERVER_HELLO,SSL_R_REUSE_CIPHER_LIST_NOT_ZERO);
			return(-1);
			}
		}
	else
		{
#ifdef undef
		/* very bad */
		memset(s->session->session_id,0,
			SSL_MAX_SSL_SESSION_ID_LENGTH_IN_BYTES);
		s->session->session_id_length=0;
		*/
#endif

		/* we need to do this in case we were trying to reuse a 
		 * client session but others are already reusing it.
		 * If this was a new 'blank' session ID, the session-id
		 * length will still be 0 */
		if (s->session->session_id_length > 0)
			{
			if (!ssl_get_new_session(s,0))
				{
				ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
				return(-1);
				}
			}

		if (ssl2_set_certificate(s,s->s2->tmp.cert_type,
			s->s2->tmp.cert_length,p) <= 0)
			{
			ssl2_return_error(s,SSL2_PE_BAD_CERTIFICATE);
			return(-1);
			}
		p+=s->s2->tmp.cert_length;

		if (s->s2->tmp.csl == 0)
			{
			ssl2_return_error(s,SSL2_PE_NO_CIPHER);
			SSLerr(SSL_F_GET_SERVER_HELLO,SSL_R_NO_CIPHER_LIST);
			return(-1);
			}

		/* We have just received a list of ciphers back from the
		 * server.  We need to get the ones that match, then select
		 * the one we want the most :-). */

		/* load the ciphers */
		sk=ssl_bytes_to_cipher_list(s,p,s->s2->tmp.csl,
					    &s->session->ciphers);
		p+=s->s2->tmp.csl;
		if (sk == NULL)
			{
			ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
			SSLerr(SSL_F_GET_SERVER_HELLO,ERR_R_MALLOC_FAILURE);
			return(-1);
			}

		(void)sk_SSL_CIPHER_set_cmp_func(sk,ssl_cipher_ptr_id_cmp);

		/* get the array of ciphers we will accept */
		cl=SSL_get_ciphers(s);
		(void)sk_SSL_CIPHER_set_cmp_func(cl,ssl_cipher_ptr_id_cmp);

		/*
		 * If server preference flag set, choose the first
		 * (highest priority) cipher the server sends, otherwise
		 * client preference has priority.
		 */
		if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE)
		    {
		    prio = sk;
		    allow = cl;
		    }
		else
		    {
		    prio = cl;
		    allow = sk;
		    }
		/* In theory we could have ciphers sent back that we
		 * don't want to use but that does not matter since we
		 * will check against the list we originally sent and
		 * for performance reasons we should not bother to match
		 * the two lists up just to check. */
		for (i=0; i<sk_SSL_CIPHER_num(prio); i++)
			{
			if (sk_SSL_CIPHER_find(allow,
					     sk_SSL_CIPHER_value(prio,i)) >= 0)
				break;
			}

		if (i >= sk_SSL_CIPHER_num(prio))
			{
			ssl2_return_error(s,SSL2_PE_NO_CIPHER);
			SSLerr(SSL_F_GET_SERVER_HELLO,SSL_R_NO_CIPHER_MATCH);
			return(-1);
			}
		s->session->cipher=sk_SSL_CIPHER_value(prio,i);


		if (s->session->peer != NULL) /* can't happen*/
			{
			ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);
			SSLerr(SSL_F_GET_SERVER_HELLO, ERR_R_INTERNAL_ERROR);
			return(-1);
			}

		s->session->peer = s->session->sess_cert->peer_key->x509;
		/* peer_key->x509 has been set by ssl2_set_certificate. */
		CRYPTO_add(&s->session->peer->references, 1, CRYPTO_LOCK_X509);
		}

	if (s->session->sess_cert == NULL 
      || s->session->peer != s->session->sess_cert->peer_key->x509)
		/* can't happen */
		{
		ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);
		SSLerr(SSL_F_GET_SERVER_HELLO, ERR_R_INTERNAL_ERROR);
		return(-1);
		}
		
	s->s2->conn_id_length=s->s2->tmp.conn_id_length;
	if (s->s2->conn_id_length > sizeof s->s2->conn_id)
		{
		ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);
		SSLerr(SSL_F_GET_SERVER_HELLO, SSL_R_SSL2_CONNECTION_ID_TOO_LONG);
		return -1;
		}
	memcpy(s->s2->conn_id,p,s->s2->tmp.conn_id_length);
	return(1);
	}
Example #4
0
	if (pbe_ciph)
		pbe_nid = -1;

	if (!(bag->value.shkeybag = PKCS8_encrypt(pbe_nid, pbe_ciph, pass,
	    passlen, salt, saltlen, iter, p8))) {
		PKCS12err(PKCS12_F_PKCS12_MAKE_SHKEYBAG, ERR_R_MALLOC_FAILURE);
		return NULL;
	}

	return bag;
}

/* Turn a stack of SAFEBAGS into a PKCS#7 data Contentinfo */
PKCS7 *
PKCS12_pack_p7data(STACK_OF(PKCS12_SAFEBAG) *sk)
{
	PKCS7 *p7;

	if (!(p7 = PKCS7_new())) {
		PKCS12err(PKCS12_F_PKCS12_PACK_P7DATA, ERR_R_MALLOC_FAILURE);
		return NULL;
	}
	p7->type = OBJ_nid2obj(NID_pkcs7_data);
	if (!(p7->d.data = M_ASN1_OCTET_STRING_new())) {
		PKCS12err(PKCS12_F_PKCS12_PACK_P7DATA, ERR_R_MALLOC_FAILURE);
		return NULL;
	}

	if (!ASN1_item_pack(sk, ASN1_ITEM_rptr(PKCS12_SAFEBAGS), &p7->d.data)) {
		PKCS12err(PKCS12_F_PKCS12_PACK_P7DATA,
Example #5
0
static int
int_engine_configure(char *name, char *value, const CONF *cnf)
{
	int i;
	int ret = 0;
	long do_init = -1;
	STACK_OF(CONF_VALUE) *ecmds;
	CONF_VALUE *ecmd = NULL;
	char *ctrlname, *ctrlvalue;
	ENGINE *e = NULL;
	int soft = 0;

	name = skip_dot(name);
#ifdef ENGINE_CONF_DEBUG
	fprintf(stderr, "Configuring engine %s\n", name);
#endif
	/* Value is a section containing ENGINE commands */
	ecmds = NCONF_get_section(cnf, value);

	if (!ecmds) {
		ENGINEerror(ENGINE_R_ENGINE_SECTION_ERROR);
		return 0;
	}

	for (i = 0; i < sk_CONF_VALUE_num(ecmds); i++) {
		ecmd = sk_CONF_VALUE_value(ecmds, i);
		ctrlname = skip_dot(ecmd->name);
		ctrlvalue = ecmd->value;
#ifdef ENGINE_CONF_DEBUG
		fprintf(stderr, "ENGINE conf: doing ctrl(%s,%s)\n",
		    ctrlname, ctrlvalue);
#endif

		/* First handle some special pseudo ctrls */

		/* Override engine name to use */
		if (!strcmp(ctrlname, "engine_id"))
			name = ctrlvalue;
		else if (!strcmp(ctrlname, "soft_load"))
			soft = 1;
		/* Load a dynamic ENGINE */
		else if (!strcmp(ctrlname, "dynamic_path")) {
			e = ENGINE_by_id("dynamic");
			if (!e)
				goto err;
			if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", ctrlvalue, 0))
				goto err;
			if (!ENGINE_ctrl_cmd_string(e, "LIST_ADD", "2", 0))
				goto err;
			if (!ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0))
				goto err;
		}
		/* ... add other pseudos here ... */
		else {
			/* At this point we need an ENGINE structural reference
			 * if we don't already have one.
			 */
			if (!e) {
				e = ENGINE_by_id(name);
				if (!e && soft) {
					ERR_clear_error();
					return 1;
				}
				if (!e)
					goto err;
			}
			/* Allow "EMPTY" to mean no value: this allows a valid
			 * "value" to be passed to ctrls of type NO_INPUT
		 	 */
			if (!strcmp(ctrlvalue, "EMPTY"))
				ctrlvalue = NULL;
			if (!strcmp(ctrlname, "init")) {
				if (!NCONF_get_number_e(cnf, value, "init",
				    &do_init))
					goto err;
				if (do_init == 1) {
					if (!int_engine_init(e))
						goto err;
				} else if (do_init != 0) {
					ENGINEerror(ENGINE_R_INVALID_INIT_VALUE);
					goto err;
				}
			}
			else if (!strcmp(ctrlname, "default_algorithms")) {
				if (!ENGINE_set_default_string(e, ctrlvalue))
					goto err;
			} else if (!ENGINE_ctrl_cmd_string(e,
				ctrlname, ctrlvalue, 0))
				goto err;
		}
	}
	if (e && (do_init == -1) && !int_engine_init(e)) {
		ecmd = NULL;
		goto err;
	}
	ret = 1;

err:
	if (ret != 1) {
		ENGINEerror(ENGINE_R_ENGINE_CONFIGURATION_ERROR);
		if (ecmd)
			ERR_asprintf_error_data(
			    "section=%s, name=%s, value=%s",
			    ecmd->section, ecmd->name, ecmd->value);
	}
	if (e)
		ENGINE_free(e);
	return ret;
}
Example #6
0
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * ([email protected]).  This product includes software written by Tim
 * Hudson ([email protected]).
 *
 */

#include <stdio.h>
#include "cryptlib.h"
#include <openssl/pkcs12.h>


static int pkcs12_add_bag(STACK_OF(PKCS12_SAFEBAG) **pbags, PKCS12_SAFEBAG *bag);

PKCS12 *PKCS12_create(char *pass, char *name, EVP_PKEY *pkey, X509 *cert,
	     STACK_OF(X509) *ca, int nid_key, int nid_cert, int iter, int mac_iter,
	     int keytype)
{
	PKCS12 *p12 = NULL;
	STACK_OF(PKCS7) *safes = NULL;
	STACK_OF(PKCS12_SAFEBAG) *bags = NULL;
	PKCS12_SAFEBAG *bag = NULL;
	int i;
	unsigned char keyid[EVP_MAX_MD_SIZE];
	unsigned int keyidlen = 0;

	/* Set defaults */
	if (!nid_cert)
Example #7
0
 * ([email protected]).  This product includes software written by Tim
 * Hudson ([email protected]).
 *
 */

/* Simple PKCS#7 processing functions */

#include <stdio.h>
#include "cryptlib.h"
#include <openssl/x509.h>
#include <openssl/x509v3.h>

static int pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si);

PKCS7 *
PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, BIO *data,
    int flags)
{
	PKCS7 *p7;
	int i;

	if (!(p7 = PKCS7_new())) {
		PKCS7err(PKCS7_F_PKCS7_SIGN, ERR_R_MALLOC_FAILURE);
		return NULL;
	}

	if (!PKCS7_set_type(p7, NID_pkcs7_signed))
		goto err;

	if (!PKCS7_content_new(p7, NID_pkcs7_data))
		goto err;
Example #8
0
int main(int argc, char **argv)
{
    char *opt_input = NULL,
        *opt_output = NULL,
        *opt_key = NULL,
        *opt_engine = NULL,
        *opt_password = NULL;
    int long_optind = 0, ret = 1;
    int encrypt = 0, decrypt = 0, verbose = 0, quiet = 0;
    STACK_OF(X509) *crts = sk_X509_new_null();
    X509 *x509 = NULL;
    EVP_PKEY *key = NULL;
    BIO *in = NULL, *out = NULL, *err = NULL;
    ENGINE *engine = NULL;

    init_crypto();

    while (1) {
        char c = getopt_long(argc, argv, "deE:hi:k:o:p:qr:v",
                             options, &long_optind);
        if (c == -1)
            break;
        switch (c) {
            case 'd':
                decrypt = 1;
                break;
            case 'E':
                opt_engine = optarg;
                break;
            case 'e':
                encrypt = 1;
                break;
            case 'i':
                opt_input = optarg;
                break;
            case 'k':
                opt_key = optarg;
                break;
            case 'o':
                opt_output = optarg;
                break;
            case 'p':
                opt_password = optarg;
                break;
            case 'q':
                quiet = 1;
                break;
            case 'r':
                x509 = load_x509(NULL, optarg);
                if(x509) {
                    sk_X509_push(crts, x509);
                } else {
                    fprintf(stderr, "Error loading certificate '%s'\n", optarg);
                    goto end;
                }
                break;
            case 'v':
                verbose += 1;
                break;
            case 'h':
            default:
                print_usage_and_die(app_name, options, option_help);
        }
    }

    if(encrypt == 0 && decrypt == 0) {
        fprintf(stderr, "You must specify either --encrypt/-e or --decrypt/-d\n");
        goto end;
    }

    err = BIO_new_fp(stderr, BIO_NOCLOSE);
    if(err == NULL) {
        fprintf(stderr, "Error allocating error stream\n");
    }

    if(opt_engine) {
        engine = load_engine(err, opt_engine, verbose);
    }

    if(opt_key) {
        if((key = load_key(NULL, opt_key, engine)) == NULL) {
            fprintf(stderr, "Error loading key '%s'\n", opt_key);
            goto end;
        }
    }

    if(opt_input) {
        in = BIO_new_file(opt_input, "rb");
    } else {
        in = BIO_new_fp(stdin, BIO_NOCLOSE);
    }

    if(opt_output) {
        out = BIO_new_file(opt_output, "wb");
    } else {
        out = BIO_new_fp(stdout, BIO_NOCLOSE);
    }

    if(encrypt) {
        if(opt_password == NULL && sk_X509_num(crts) == 0) {
            fprintf(stderr, "You must specify at least one of --password/-p or --recipient/-r\n");
            goto end;
        }
        ret = encrypt_cms(in, out, err, opt_password, crts);
    } else if(decrypt) {
        if(opt_password == NULL && (opt_key == NULL || sk_X509_num(crts) == 0)) {
            fprintf(stderr, "You must specify either --password/-p or --recipient/-r and --key/-k\n");
            goto end;
        }
        ret = decrypt_cms(in, out, err, opt_password, x509, key);
    }

 end:
    return ret;
}
Example #9
0
int MAIN(int argc, char **argv)
	{
	ENGINE *e = NULL;
	int ret=1;
	X509_REQ *req=NULL;
	X509 *x=NULL,*xca=NULL;
	ASN1_OBJECT *objtmp;
	EVP_PKEY *Upkey=NULL,*CApkey=NULL;
	ASN1_INTEGER *sno = NULL;
	int i,num,badops=0;
	BIO *out=NULL;
	BIO *STDout=NULL;
	STACK_OF(ASN1_OBJECT) *trust = NULL, *reject = NULL;
	int informat,outformat,keyformat,CAformat,CAkeyformat;
	char *infile=NULL,*outfile=NULL,*keyfile=NULL,*CAfile=NULL;
	char *CAkeyfile=NULL,*CAserial=NULL;
	char *alias=NULL;
	int text=0,serial=0,subject=0,issuer=0,startdate=0,enddate=0;
	int next_serial=0;
	int subject_hash=0,issuer_hash=0,ocspid=0;
	int noout=0,sign_flag=0,CA_flag=0,CA_createserial=0,email=0;
	int ocsp_uri=0;
	int trustout=0,clrtrust=0,clrreject=0,aliasout=0,clrext=0;
	int C=0;
	int x509req=0,days=DEF_DAYS,modulus=0,pubkey=0;
	int pprint = 0;
	const char **pp;
	X509_STORE *ctx=NULL;
	X509_REQ *rq=NULL;
	int fingerprint=0;
	char buf[256];
	const EVP_MD *md_alg,*digest=EVP_sha1();
	CONF *extconf = NULL;
	char *extsect = NULL, *extfile = NULL, *passin = NULL, *passargin = NULL;
	int need_rand = 0;
	int checkend=0,checkoffset=0;
	unsigned long nmflag = 0, certflag = 0;
#ifndef OPENSSL_NO_ENGINE
	char *engine=NULL;
#endif

	reqfile=0;

	apps_startup();

	if (bio_err == NULL)
		bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);

	if (!load_config(bio_err, NULL))
		goto end;
	STDout=BIO_new_fp(stdout,BIO_NOCLOSE);
#ifdef OPENSSL_SYS_VMS
	{
	BIO *tmpbio = BIO_new(BIO_f_linebuffer());
	STDout = BIO_push(tmpbio, STDout);
	}
#endif

	informat=FORMAT_PEM;
	outformat=FORMAT_PEM;
	keyformat=FORMAT_PEM;
	CAformat=FORMAT_PEM;
	CAkeyformat=FORMAT_PEM;

	ctx=X509_STORE_new();
	if (ctx == NULL) goto end;
	X509_STORE_set_verify_cb_func(ctx,callb);

	argc--;
	argv++;
	num=0;
	while (argc >= 1)
		{
		if 	(strcmp(*argv,"-inform") == 0)
			{
			if (--argc < 1) goto bad;
			informat=str2fmt(*(++argv));
			}
		else if (strcmp(*argv,"-outform") == 0)
			{
			if (--argc < 1) goto bad;
			outformat=str2fmt(*(++argv));
			}
		else if (strcmp(*argv,"-keyform") == 0)
			{
			if (--argc < 1) goto bad;
			keyformat=str2fmt(*(++argv));
			}
		else if (strcmp(*argv,"-req") == 0)
			{
			reqfile=1;
			need_rand = 1;
			}
		else if (strcmp(*argv,"-CAform") == 0)
			{
			if (--argc < 1) goto bad;
			CAformat=str2fmt(*(++argv));
			}
		else if (strcmp(*argv,"-CAkeyform") == 0)
			{
			if (--argc < 1) goto bad;
			CAkeyformat=str2fmt(*(++argv));
			}
		else if (strcmp(*argv,"-days") == 0)
			{
			if (--argc < 1) goto bad;
			days=atoi(*(++argv));
			if (days == 0)
				{
				BIO_printf(STDout,"bad number of days\n");
				goto bad;
				}
			}
		else if (strcmp(*argv,"-passin") == 0)
			{
			if (--argc < 1) goto bad;
			passargin= *(++argv);
			}
		else if (strcmp(*argv,"-extfile") == 0)
			{
			if (--argc < 1) goto bad;
			extfile= *(++argv);
			}
		else if (strcmp(*argv,"-extensions") == 0)
			{
			if (--argc < 1) goto bad;
			extsect= *(++argv);
			}
		else if (strcmp(*argv,"-in") == 0)
			{
			if (--argc < 1) goto bad;
			infile= *(++argv);
			}
		else if (strcmp(*argv,"-out") == 0)
			{
			if (--argc < 1) goto bad;
			outfile= *(++argv);
			}
		else if (strcmp(*argv,"-signkey") == 0)
			{
			if (--argc < 1) goto bad;
			keyfile= *(++argv);
			sign_flag= ++num;
			need_rand = 1;
			}
		else if (strcmp(*argv,"-CA") == 0)
			{
			if (--argc < 1) goto bad;
			CAfile= *(++argv);
			CA_flag= ++num;
			need_rand = 1;
			}
		else if (strcmp(*argv,"-CAkey") == 0)
			{
			if (--argc < 1) goto bad;
			CAkeyfile= *(++argv);
			}
		else if (strcmp(*argv,"-CAserial") == 0)
			{
			if (--argc < 1) goto bad;
			CAserial= *(++argv);
			}
		else if (strcmp(*argv,"-set_serial") == 0)
			{
			if (--argc < 1) goto bad;
			if (!(sno = s2i_ASN1_INTEGER(NULL, *(++argv))))
				goto bad;
			}
		else if (strcmp(*argv,"-addtrust") == 0)
			{
			if (--argc < 1) goto bad;
			if (!(objtmp = OBJ_txt2obj(*(++argv), 0)))
				{
				BIO_printf(bio_err,
					"Invalid trust object value %s\n", *argv);
				goto bad;
				}
			if (!trust) trust = sk_ASN1_OBJECT_new_null();
			sk_ASN1_OBJECT_push(trust, objtmp);
			trustout = 1;
			}
		else if (strcmp(*argv,"-addreject") == 0)
			{
			if (--argc < 1) goto bad;
			if (!(objtmp = OBJ_txt2obj(*(++argv), 0)))
				{
				BIO_printf(bio_err,
					"Invalid reject object value %s\n", *argv);
				goto bad;
				}
			if (!reject) reject = sk_ASN1_OBJECT_new_null();
			sk_ASN1_OBJECT_push(reject, objtmp);
			trustout = 1;
			}
		else if (strcmp(*argv,"-setalias") == 0)
			{
			if (--argc < 1) goto bad;
			alias= *(++argv);
			trustout = 1;
			}
		else if (strcmp(*argv,"-certopt") == 0)
			{
			if (--argc < 1) goto bad;
			if (!set_cert_ex(&certflag, *(++argv))) goto bad;
			}
		else if (strcmp(*argv,"-nameopt") == 0)
			{
			if (--argc < 1) goto bad;
			if (!set_name_ex(&nmflag, *(++argv))) goto bad;
			}
#ifndef OPENSSL_NO_ENGINE
		else if (strcmp(*argv,"-engine") == 0)
			{
			if (--argc < 1) goto bad;
			engine= *(++argv);
			}
#endif
		else if (strcmp(*argv,"-C") == 0)
			C= ++num;
		else if (strcmp(*argv,"-email") == 0)
			email= ++num;
		else if (strcmp(*argv,"-ocsp_uri") == 0)
			ocsp_uri= ++num;
		else if (strcmp(*argv,"-serial") == 0)
			serial= ++num;
		else if (strcmp(*argv,"-next_serial") == 0)
			next_serial= ++num;
		else if (strcmp(*argv,"-modulus") == 0)
			modulus= ++num;
		else if (strcmp(*argv,"-pubkey") == 0)
			pubkey= ++num;
		else if (strcmp(*argv,"-x509toreq") == 0)
			x509req= ++num;
		else if (strcmp(*argv,"-text") == 0)
			text= ++num;
		else if (strcmp(*argv,"-hash") == 0
			|| strcmp(*argv,"-subject_hash") == 0)
			subject_hash= ++num;
		else if (strcmp(*argv,"-issuer_hash") == 0)
			issuer_hash= ++num;
		else if (strcmp(*argv,"-subject") == 0)
			subject= ++num;
		else if (strcmp(*argv,"-issuer") == 0)
			issuer= ++num;
		else if (strcmp(*argv,"-fingerprint") == 0)
			fingerprint= ++num;
		else if (strcmp(*argv,"-dates") == 0)
			{
			startdate= ++num;
			enddate= ++num;
			}
		else if (strcmp(*argv,"-purpose") == 0)
			pprint= ++num;
		else if (strcmp(*argv,"-startdate") == 0)
			startdate= ++num;
		else if (strcmp(*argv,"-enddate") == 0)
			enddate= ++num;
		else if (strcmp(*argv,"-checkend") == 0)
			{
			if (--argc < 1) goto bad;
			checkoffset=atoi(*(++argv));
			checkend=1;
			}
		else if (strcmp(*argv,"-noout") == 0)
			noout= ++num;
		else if (strcmp(*argv,"-trustout") == 0)
			trustout= 1;
		else if (strcmp(*argv,"-clrtrust") == 0)
			clrtrust= ++num;
		else if (strcmp(*argv,"-clrreject") == 0)
			clrreject= ++num;
		else if (strcmp(*argv,"-alias") == 0)
			aliasout= ++num;
		else if (strcmp(*argv,"-CAcreateserial") == 0)
			CA_createserial= ++num;
		else if (strcmp(*argv,"-clrext") == 0)
			clrext = 1;
#if 1 /* stay backwards-compatible with 0.9.5; this should go away soon */
		else if (strcmp(*argv,"-crlext") == 0)
			{
			BIO_printf(bio_err,"use -clrext instead of -crlext\n");
			clrext = 1;
			}
#endif
		else if (strcmp(*argv,"-ocspid") == 0)
			ocspid= ++num;
		else if ((md_alg=EVP_get_digestbyname(*argv + 1)))
			{
			/* ok */
			digest=md_alg;
			}
		else
			{
			BIO_printf(bio_err,"unknown option %s\n",*argv);
			badops=1;
			break;
			}
		argc--;
		argv++;
		}

	if (badops)
		{
bad:
		for (pp=x509_usage; (*pp != NULL); pp++)
			BIO_printf(bio_err,"%s",*pp);
		goto end;
		}

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

	if (need_rand)
		app_RAND_load_file(NULL, bio_err, 0);

	ERR_load_crypto_strings();

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

	if (!X509_STORE_set_default_paths(ctx))
		{
		ERR_print_errors(bio_err);
		goto end;
		}

	if ((CAkeyfile == NULL) && (CA_flag) && (CAformat == FORMAT_PEM))
		{ CAkeyfile=CAfile; }
	else if ((CA_flag) && (CAkeyfile == NULL))
		{
		BIO_printf(bio_err,"need to specify a CAkey if using the CA command\n");
		goto end;
		}

	if (extfile)
		{
		long errorline = -1;
		X509V3_CTX ctx2;
		extconf = NCONF_new(NULL);
		if (!NCONF_load(extconf, extfile,&errorline))
			{
			if (errorline <= 0)
				BIO_printf(bio_err,
					"error loading the config file '%s'\n",
								extfile);
                	else
                        	BIO_printf(bio_err,
				       "error on line %ld of config file '%s'\n"
							,errorline,extfile);
			goto end;
			}
		if (!extsect)
			{
			extsect = NCONF_get_string(extconf, "default", "extensions");
			if (!extsect)
				{
				ERR_clear_error();
				extsect = "default";
				}
			}
		X509V3_set_ctx_test(&ctx2);
		X509V3_set_nconf(&ctx2, extconf);
		if (!X509V3_EXT_add_nconf(extconf, &ctx2, extsect, NULL))
			{
			BIO_printf(bio_err,
				"Error Loading extension section %s\n",
								 extsect);
			ERR_print_errors(bio_err);
			goto end;
			}
		}


	if (reqfile)
		{
		EVP_PKEY *pkey;
		BIO *in;

		if (!sign_flag && !CA_flag)
			{
			BIO_printf(bio_err,"We need a private key to sign with\n");
			goto end;
			}
		in=BIO_new(BIO_s_file());
		if (in == NULL)
			{
			ERR_print_errors(bio_err);
			goto end;
			}

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

		if (req == NULL)
			{
			ERR_print_errors(bio_err);
			goto end;
			}

		if (	(req->req_info == NULL) ||
			(req->req_info->pubkey == NULL) ||
			(req->req_info->pubkey->public_key == NULL) ||
			(req->req_info->pubkey->public_key->data == NULL))
			{
			BIO_printf(bio_err,"The certificate request appears to corrupted\n");
			BIO_printf(bio_err,"It does not contain a public key\n");
			goto end;
			}
		if ((pkey=X509_REQ_get_pubkey(req)) == NULL)
	                {
	                BIO_printf(bio_err,"error unpacking public key\n");
	                goto end;
	                }
		i=X509_REQ_verify(req,pkey);
		EVP_PKEY_free(pkey);
		if (i < 0)
			{
			BIO_printf(bio_err,"Signature verification error\n");
			ERR_print_errors(bio_err);
			goto end;
			}
	        if (i == 0)
			{
			BIO_printf(bio_err,"Signature did not match the certificate request\n");
			goto end;
			}
		else
			BIO_printf(bio_err,"Signature ok\n");

		print_name(bio_err, "subject=", X509_REQ_get_subject_name(req), nmflag);

		if ((x=X509_new()) == NULL) goto end;

		if (sno == NULL)
			{
			sno = ASN1_INTEGER_new();
			if (!sno || !rand_serial(NULL, sno))
				goto end;
			if (!X509_set_serialNumber(x, sno)) 
				goto end;
			ASN1_INTEGER_free(sno);
			sno = NULL;
			}
		else if (!X509_set_serialNumber(x, sno)) 
			goto end;

		if (!X509_set_issuer_name(x,req->req_info->subject)) goto end;
		if (!X509_set_subject_name(x,req->req_info->subject)) goto end;

		X509_gmtime_adj(X509_get_notBefore(x),0);
	        X509_gmtime_adj(X509_get_notAfter(x),(long)60*60*24*days);

		pkey = X509_REQ_get_pubkey(req);
		X509_set_pubkey(x,pkey);
		EVP_PKEY_free(pkey);
		}
	else
		x=load_cert(bio_err,infile,informat,NULL,e,"Certificate");

	if (x == NULL) goto end;
	if (CA_flag)
		{
		xca=load_cert(bio_err,CAfile,CAformat,NULL,e,"CA Certificate");
		if (xca == NULL) goto end;
		}

	if (!noout || text || next_serial)
		{
		OBJ_create("2.99999.3",
			"SET.ex3","SET x509v3 extension 3");

		out=BIO_new(BIO_s_file());
		if (out == NULL)
			{
			ERR_print_errors(bio_err);
			goto end;
			}
		if (outfile == NULL)
			{
			BIO_set_fp(out,stdout,BIO_NOCLOSE);
#ifdef OPENSSL_SYS_VMS
			{
			BIO *tmpbio = BIO_new(BIO_f_linebuffer());
			out = BIO_push(tmpbio, out);
			}
#endif
			}
		else
			{
			if (BIO_write_filename(out,outfile) <= 0)
				{
				perror(outfile);
				goto end;
				}
			}
		}

	if (alias) X509_alias_set1(x, (unsigned char *)alias, -1);

	if (clrtrust) X509_trust_clear(x);
	if (clrreject) X509_reject_clear(x);

	if (trust)
		{
		for (i = 0; i < sk_ASN1_OBJECT_num(trust); i++)
			{
			objtmp = sk_ASN1_OBJECT_value(trust, i);
			X509_add1_trust_object(x, objtmp);
			}
		}

	if (reject)
		{
		for (i = 0; i < sk_ASN1_OBJECT_num(reject); i++)
			{
			objtmp = sk_ASN1_OBJECT_value(reject, i);
			X509_add1_reject_object(x, objtmp);
			}
		}

	if (num)
		{
		for (i=1; i<=num; i++)
			{
			if (issuer == i)
				{
				print_name(STDout, "issuer= ",
					X509_get_issuer_name(x), nmflag);
				}
			else if (subject == i) 
				{
				print_name(STDout, "subject= ",
					X509_get_subject_name(x), nmflag);
				}
			else if (serial == i)
				{
				BIO_printf(STDout,"serial=");
				i2a_ASN1_INTEGER(STDout,
					X509_get_serialNumber(x));
				BIO_printf(STDout,"\n");
				}
			else if (next_serial == i)
				{
				BIGNUM *bnser;
				ASN1_INTEGER *ser;
				ser = X509_get_serialNumber(x);
				bnser = ASN1_INTEGER_to_BN(ser, NULL);
				if (!bnser)
					goto end;
				if (!BN_add_word(bnser, 1))
					goto end;
				ser = BN_to_ASN1_INTEGER(bnser, NULL);
				if (!ser)
					goto end;
				BN_free(bnser);
				i2a_ASN1_INTEGER(out, ser);
				ASN1_INTEGER_free(ser);
				BIO_puts(out, "\n");
				}
			else if ((email == i) || (ocsp_uri == i))
				{
				int j;
				STACK *emlst;
				if (email == i)
					emlst = X509_get1_email(x);
				else
					emlst = X509_get1_ocsp(x);
				for (j = 0; j < sk_num(emlst); j++)
					BIO_printf(STDout, "%s\n", sk_value(emlst, j));
				X509_email_free(emlst);
				}
			else if (aliasout == i)
				{
				unsigned char *alstr;
				alstr = X509_alias_get0(x, NULL);
				if (alstr) BIO_printf(STDout,"%s\n", alstr);
				else BIO_puts(STDout,"<No Alias>\n");
				}
			else if (subject_hash == i)
				{
				BIO_printf(STDout,"%08lx\n",X509_subject_name_hash(x));
				}
			else if (issuer_hash == i)
				{
				BIO_printf(STDout,"%08lx\n",X509_issuer_name_hash(x));
				}
			else if (pprint == i)
				{
				X509_PURPOSE *ptmp;
				int j;
				BIO_printf(STDout, "Certificate purposes:\n");
				for (j = 0; j < X509_PURPOSE_get_count(); j++)
					{
					ptmp = X509_PURPOSE_get0(j);
					purpose_print(STDout, x, ptmp);
					}
				}
			else
				if (modulus == i)
				{
				EVP_PKEY *pkey;

				pkey=X509_get_pubkey(x);
				if (pkey == NULL)
					{
					BIO_printf(bio_err,"Modulus=unavailable\n");
					ERR_print_errors(bio_err);
					goto end;
					}
				BIO_printf(STDout,"Modulus=");
#ifndef OPENSSL_NO_RSA
				if (pkey->type == EVP_PKEY_RSA)
					BN_print(STDout,pkey->pkey.rsa->n);
				else
#endif
#ifndef OPENSSL_NO_DSA
				if (pkey->type == EVP_PKEY_DSA)
					BN_print(STDout,pkey->pkey.dsa->pub_key);
				else
#endif
					BIO_printf(STDout,"Wrong Algorithm type");
				BIO_printf(STDout,"\n");
				EVP_PKEY_free(pkey);
				}
			else
				if (pubkey == i)
				{
				EVP_PKEY *pkey;

				pkey=X509_get_pubkey(x);
				if (pkey == NULL)
					{
					BIO_printf(bio_err,"Error getting public key\n");
					ERR_print_errors(bio_err);
					goto end;
					}
				PEM_write_bio_PUBKEY(STDout, pkey);
				EVP_PKEY_free(pkey);
				}
			else
				if (C == i)
				{
				unsigned char *d;
				char *m;
				int y,z;

				X509_NAME_oneline(X509_get_subject_name(x),
					buf,sizeof buf);
				BIO_printf(STDout,"/* subject:%s */\n",buf);
				m=X509_NAME_oneline(
					X509_get_issuer_name(x),buf,
					sizeof buf);
				BIO_printf(STDout,"/* issuer :%s */\n",buf);

				z=i2d_X509(x,NULL);
				m=OPENSSL_malloc(z);

				d=(unsigned char *)m;
				z=i2d_X509_NAME(X509_get_subject_name(x),&d);
				BIO_printf(STDout,"unsigned char XXX_subject_name[%d]={\n",z);
				d=(unsigned char *)m;
				for (y=0; y<z; y++)
					{
					BIO_printf(STDout,"0x%02X,",d[y]);
					if ((y & 0x0f) == 0x0f) BIO_printf(STDout,"\n");
					}
				if (y%16 != 0) BIO_printf(STDout,"\n");
				BIO_printf(STDout,"};\n");

				z=i2d_X509_PUBKEY(X509_get_X509_PUBKEY(x),&d);
				BIO_printf(STDout,"unsigned char XXX_public_key[%d]={\n",z);
				d=(unsigned char *)m;
				for (y=0; y<z; y++)
					{
					BIO_printf(STDout,"0x%02X,",d[y]);
					if ((y & 0x0f) == 0x0f)
						BIO_printf(STDout,"\n");
					}
				if (y%16 != 0) BIO_printf(STDout,"\n");
				BIO_printf(STDout,"};\n");

				z=i2d_X509(x,&d);
				BIO_printf(STDout,"unsigned char XXX_certificate[%d]={\n",z);
				d=(unsigned char *)m;
				for (y=0; y<z; y++)
					{
					BIO_printf(STDout,"0x%02X,",d[y]);
					if ((y & 0x0f) == 0x0f)
						BIO_printf(STDout,"\n");
					}
				if (y%16 != 0) BIO_printf(STDout,"\n");
				BIO_printf(STDout,"};\n");

				OPENSSL_free(m);
				}
			else if (text == i)
				{
				X509_print_ex(out,x,nmflag, certflag);
				}
			else if (startdate == i)
				{
				BIO_puts(STDout,"notBefore=");
				ASN1_TIME_print(STDout,X509_get_notBefore(x));
				BIO_puts(STDout,"\n");
				}
			else if (enddate == i)
				{
				BIO_puts(STDout,"notAfter=");
				ASN1_TIME_print(STDout,X509_get_notAfter(x));
				BIO_puts(STDout,"\n");
				}
			else if (fingerprint == i)
				{
				int j;
				unsigned int n;
				unsigned char md[EVP_MAX_MD_SIZE];

				if (!X509_digest(x,digest,md,&n))
					{
					BIO_printf(bio_err,"out of memory\n");
					goto end;
					}
				BIO_printf(STDout,"%s Fingerprint=",
						OBJ_nid2sn(EVP_MD_type(digest)));
				for (j=0; j<(int)n; j++)
					{
					BIO_printf(STDout,"%02X%c",md[j],
						(j+1 == (int)n)
						?'\n':':');
					}
				}

			/* should be in the library */
			else if ((sign_flag == i) && (x509req == 0))
				{
				BIO_printf(bio_err,"Getting Private key\n");
				if (Upkey == NULL)
					{
					Upkey=load_key(bio_err,
						keyfile, keyformat, 0,
						passin, e, "Private key");
					if (Upkey == NULL) goto end;
					}
#ifndef OPENSSL_NO_DSA
		                if (Upkey->type == EVP_PKEY_DSA)
		                        digest=EVP_dss1();
#endif
#ifndef OPENSSL_NO_ECDSA
				if (Upkey->type == EVP_PKEY_EC)
					digest=EVP_ecdsa();
#endif

				assert(need_rand);
				if (!sign(x,Upkey,days,clrext,digest,
						 extconf, extsect)) goto end;
				}
			else if (CA_flag == i)
				{
				BIO_printf(bio_err,"Getting CA Private Key\n");
				if (CAkeyfile != NULL)
					{
					CApkey=load_key(bio_err,
						CAkeyfile, CAkeyformat,
						0, passin, e,
						"CA Private Key");
					if (CApkey == NULL) goto end;
					}
#ifndef OPENSSL_NO_DSA
		                if (CApkey->type == EVP_PKEY_DSA)
		                        digest=EVP_dss1();
#endif
#ifndef OPENSSL_NO_ECDSA
				if (CApkey->type == EVP_PKEY_EC)
					digest = EVP_ecdsa();
#endif
				
				assert(need_rand);
				if (!x509_certify(ctx,CAfile,digest,x,xca,
					CApkey, CAserial,CA_createserial,days, clrext,
					extconf, extsect, sno))
					goto end;
				}
			else if (x509req == i)
				{
				EVP_PKEY *pk;

				BIO_printf(bio_err,"Getting request Private Key\n");
				if (keyfile == NULL)
					{
					BIO_printf(bio_err,"no request key file specified\n");
					goto end;
					}
				else
					{
					pk=load_key(bio_err,
						keyfile, FORMAT_PEM, 0,
						passin, e, "request key");
					if (pk == NULL) goto end;
					}

				BIO_printf(bio_err,"Generating certificate request\n");

#ifndef OPENSSL_NO_DSA
		                if (pk->type == EVP_PKEY_DSA)
		                        digest=EVP_dss1();
#endif
#ifndef OPENSSL_NO_ECDSA
				if (pk->type == EVP_PKEY_EC)
					digest=EVP_ecdsa();
#endif

				rq=X509_to_X509_REQ(x,pk,digest);
				EVP_PKEY_free(pk);
				if (rq == NULL)
					{
					ERR_print_errors(bio_err);
					goto end;
					}
				if (!noout)
					{
					X509_REQ_print(out,rq);
					PEM_write_bio_X509_REQ(out,rq);
					}
				noout=1;
				}
			else if (ocspid == i)
				{
				X509_ocspid_print(out, x);
				}
			}
		}

	if (checkend)
		{
		time_t tcheck=time(NULL) + checkoffset;

		if (X509_cmp_time(X509_get_notAfter(x), &tcheck) < 0)
			{
			BIO_printf(out,"Certificate will expire\n");
			ret=1;
			}
		else
			{
			BIO_printf(out,"Certificate will not expire\n");
			ret=0;
			}
		goto end;
		}

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

	if 	(outformat == FORMAT_ASN1)
		i=i2d_X509_bio(out,x);
	else if (outformat == FORMAT_PEM)
		{
		if (trustout) i=PEM_write_bio_X509_AUX(out,x);
		else i=PEM_write_bio_X509(out,x);
		}
	else if (outformat == FORMAT_NETSCAPE)
		{
		ASN1_HEADER ah;
		ASN1_OCTET_STRING os;

		os.data=(unsigned char *)NETSCAPE_CERT_HDR;
		os.length=strlen(NETSCAPE_CERT_HDR);
		ah.header= &os;
		ah.data=(char *)x;
		ah.meth=X509_asn1_meth();

		i=ASN1_i2d_bio_of(ASN1_HEADER,i2d_ASN1_HEADER,out,&ah);
		}
	else	{
		BIO_printf(bio_err,"bad output format specified for outfile\n");
		goto end;
		}
	if (!i)
		{
		BIO_printf(bio_err,"unable to write certificate\n");
		ERR_print_errors(bio_err);
		goto end;
		}
	ret=0;
end:
	if (need_rand)
		app_RAND_write_file(NULL, bio_err);
	OBJ_cleanup();
	NCONF_free(extconf);
	BIO_free_all(out);
	BIO_free_all(STDout);
	X509_STORE_free(ctx);
	X509_REQ_free(req);
	X509_free(x);
	X509_free(xca);
	EVP_PKEY_free(Upkey);
	EVP_PKEY_free(CApkey);
	X509_REQ_free(rq);
	ASN1_INTEGER_free(sno);
	sk_ASN1_OBJECT_pop_free(trust, ASN1_OBJECT_free);
	sk_ASN1_OBJECT_pop_free(reject, ASN1_OBJECT_free);
	if (passin) OPENSSL_free(passin);
	apps_shutdown();
	OPENSSL_EXIT(ret);
	}
Example #10
0
int MAIN(int argc, char **argv)
{
    ENGINE *e = NULL;
    char *infile = NULL, *outfile = NULL, *keyname = NULL;
    char *certfile = NULL;
    BIO *in = NULL, *out = NULL;
    char **args;
    char *name = NULL;
    char *csp_name = NULL;
    int add_lmk = 0;
    PKCS12 *p12 = NULL;
    char pass[50], macpass[50];
    int export_cert = 0;
    int options = 0;
    int chain = 0;
    int badarg = 0;
    int iter = PKCS12_DEFAULT_ITER;
    int maciter = PKCS12_DEFAULT_ITER;
    int twopass = 0;
    int keytype = 0;
    int cert_pbe;
    int key_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
    int ret = 1;
    int macver = 1;
    int noprompt = 0;
    STACK_OF(OPENSSL_STRING) *canames = NULL;
    char *cpass = NULL, *mpass = NULL;
    char *passargin = NULL, *passargout = NULL, *passarg = NULL;
    char *passin = NULL, *passout = NULL;
    char *inrand = NULL;
    char *macalg = NULL;
    char *CApath = NULL, *CAfile = NULL;
    char *engine = NULL;

    apps_startup();

    enc = EVP_des_ede3_cbc();
    if (bio_err == NULL)
        bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);

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

# ifdef OPENSSL_FIPS
    if (FIPS_mode())
        cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
    else
# endif
        cert_pbe = NID_pbe_WithSHA1And40BitRC2_CBC;

    args = argv + 1;

    while (*args) {
        if (*args[0] == '-') {
            if (!strcmp(*args, "-nokeys"))
                options |= NOKEYS;
            else if (!strcmp(*args, "-keyex"))
                keytype = KEY_EX;
            else if (!strcmp(*args, "-keysig"))
                keytype = KEY_SIG;
            else if (!strcmp(*args, "-nocerts"))
                options |= NOCERTS;
            else if (!strcmp(*args, "-clcerts"))
                options |= CLCERTS;
            else if (!strcmp(*args, "-cacerts"))
                options |= CACERTS;
            else if (!strcmp(*args, "-noout"))
                options |= (NOKEYS | NOCERTS);
            else if (!strcmp(*args, "-info"))
                options |= INFO;
            else if (!strcmp(*args, "-chain"))
                chain = 1;
            else if (!strcmp(*args, "-twopass"))
                twopass = 1;
            else if (!strcmp(*args, "-nomacver"))
                macver = 0;
            else if (!strcmp(*args, "-descert"))
                cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
            else if (!strcmp(*args, "-export"))
                export_cert = 1;
            else if (!strcmp(*args, "-des"))
                enc = EVP_des_cbc();
            else if (!strcmp(*args, "-des3"))
                enc = EVP_des_ede3_cbc();
# ifndef OPENSSL_NO_IDEA
            else if (!strcmp(*args, "-idea"))
                enc = EVP_idea_cbc();
# endif
# ifndef OPENSSL_NO_SEED
            else if (!strcmp(*args, "-seed"))
                enc = EVP_seed_cbc();
# endif
# ifndef OPENSSL_NO_AES
            else if (!strcmp(*args, "-aes128"))
                enc = EVP_aes_128_cbc();
            else if (!strcmp(*args, "-aes192"))
                enc = EVP_aes_192_cbc();
            else if (!strcmp(*args, "-aes256"))
                enc = EVP_aes_256_cbc();
# endif
# ifndef OPENSSL_NO_CAMELLIA
            else if (!strcmp(*args, "-camellia128"))
                enc = EVP_camellia_128_cbc();
            else if (!strcmp(*args, "-camellia192"))
                enc = EVP_camellia_192_cbc();
            else if (!strcmp(*args, "-camellia256"))
                enc = EVP_camellia_256_cbc();
# endif
            else if (!strcmp(*args, "-noiter"))
                iter = 1;
            else if (!strcmp(*args, "-maciter"))
                maciter = PKCS12_DEFAULT_ITER;
            else if (!strcmp(*args, "-nomaciter"))
                maciter = 1;
            else if (!strcmp(*args, "-nomac"))
                maciter = -1;
            else if (!strcmp(*args, "-macalg"))
                if (args[1]) {
                    args++;
                    macalg = *args;
                } else
                    badarg = 1;
            else if (!strcmp(*args, "-nodes"))
                enc = NULL;
            else if (!strcmp(*args, "-certpbe")) {
                if (!set_pbe(bio_err, &cert_pbe, *++args))
                    badarg = 1;
            } else if (!strcmp(*args, "-keypbe")) {
                if (!set_pbe(bio_err, &key_pbe, *++args))
                    badarg = 1;
            } else if (!strcmp(*args, "-rand")) {
                if (args[1]) {
                    args++;
                    inrand = *args;
                } else
                    badarg = 1;
            } else if (!strcmp(*args, "-inkey")) {
                if (args[1]) {
                    args++;
                    keyname = *args;
                } else
                    badarg = 1;
            } else if (!strcmp(*args, "-certfile")) {
                if (args[1]) {
                    args++;
                    certfile = *args;
                } else
                    badarg = 1;
            } else if (!strcmp(*args, "-name")) {
                if (args[1]) {
                    args++;
                    name = *args;
                } else
                    badarg = 1;
            } else if (!strcmp(*args, "-LMK"))
                add_lmk = 1;
            else if (!strcmp(*args, "-CSP")) {
                if (args[1]) {
                    args++;
                    csp_name = *args;
                } else
                    badarg = 1;
            } else if (!strcmp(*args, "-caname")) {
                if (args[1]) {
                    args++;
                    if (!canames)
                        canames = sk_OPENSSL_STRING_new_null();
                    sk_OPENSSL_STRING_push(canames, *args);
                } else
                    badarg = 1;
            } else if (!strcmp(*args, "-in")) {
                if (args[1]) {
                    args++;
                    infile = *args;
                } else
                    badarg = 1;
            } else if (!strcmp(*args, "-out")) {
                if (args[1]) {
                    args++;
                    outfile = *args;
                } else
                    badarg = 1;
            } else if (!strcmp(*args, "-passin")) {
                if (args[1]) {
                    args++;
                    passargin = *args;
                } else
                    badarg = 1;
            } else if (!strcmp(*args, "-passout")) {
                if (args[1]) {
                    args++;
                    passargout = *args;
                } else
                    badarg = 1;
            } else if (!strcmp(*args, "-password")) {
                if (args[1]) {
                    args++;
                    passarg = *args;
                    noprompt = 1;
                } else
                    badarg = 1;
            } else if (!strcmp(*args, "-CApath")) {
                if (args[1]) {
                    args++;
                    CApath = *args;
                } else
                    badarg = 1;
            } else if (!strcmp(*args, "-CAfile")) {
                if (args[1]) {
                    args++;
                    CAfile = *args;
                } else
                    badarg = 1;
# ifndef OPENSSL_NO_ENGINE
            } else if (!strcmp(*args, "-engine")) {
                if (args[1]) {
                    args++;
                    engine = *args;
                } else
                    badarg = 1;
# endif
            } else
                badarg = 1;

        } else
            badarg = 1;
        args++;
    }

    if (badarg) {
        BIO_printf(bio_err, "Usage: pkcs12 [options]\n");
        BIO_printf(bio_err, "where options are\n");
        BIO_printf(bio_err, "-export       output PKCS12 file\n");
        BIO_printf(bio_err, "-chain        add certificate chain\n");
        BIO_printf(bio_err, "-inkey file   private key if not infile\n");
        BIO_printf(bio_err, "-certfile f   add all certs in f\n");
        BIO_printf(bio_err, "-CApath arg   - PEM format directory of CA's\n");
        BIO_printf(bio_err, "-CAfile arg   - PEM format file of CA's\n");
        BIO_printf(bio_err, "-name \"name\"  use name as friendly name\n");
        BIO_printf(bio_err,
                   "-caname \"nm\"  use nm as CA friendly name (can be used more than once).\n");
        BIO_printf(bio_err, "-in  infile   input filename\n");
        BIO_printf(bio_err, "-out outfile  output filename\n");
        BIO_printf(bio_err,
                   "-noout        don't output anything, just verify.\n");
        BIO_printf(bio_err, "-nomacver     don't verify MAC.\n");
        BIO_printf(bio_err, "-nocerts      don't output certificates.\n");
        BIO_printf(bio_err,
                   "-clcerts      only output client certificates.\n");
        BIO_printf(bio_err, "-cacerts      only output CA certificates.\n");
        BIO_printf(bio_err, "-nokeys       don't output private keys.\n");
        BIO_printf(bio_err,
                   "-info         give info about PKCS#12 structure.\n");
        BIO_printf(bio_err, "-des          encrypt private keys with DES\n");
        BIO_printf(bio_err,
                   "-des3         encrypt private keys with triple DES (default)\n");
# ifndef OPENSSL_NO_IDEA
        BIO_printf(bio_err, "-idea         encrypt private keys with idea\n");
# endif
# ifndef OPENSSL_NO_SEED
        BIO_printf(bio_err, "-seed         encrypt private keys with seed\n");
# endif
# ifndef OPENSSL_NO_AES
        BIO_printf(bio_err, "-aes128, -aes192, -aes256\n");
        BIO_printf(bio_err,
                   "              encrypt PEM output with cbc aes\n");
# endif
# ifndef OPENSSL_NO_CAMELLIA
        BIO_printf(bio_err, "-camellia128, -camellia192, -camellia256\n");
        BIO_printf(bio_err,
                   "              encrypt PEM output with cbc camellia\n");
# endif
        BIO_printf(bio_err, "-nodes        don't encrypt private keys\n");
        BIO_printf(bio_err, "-noiter       don't use encryption iteration\n");
        BIO_printf(bio_err, "-nomaciter    don't use MAC iteration\n");
        BIO_printf(bio_err, "-maciter      use MAC iteration\n");
        BIO_printf(bio_err, "-nomac        don't generate MAC\n");
        BIO_printf(bio_err,
                   "-twopass      separate MAC, encryption passwords\n");
        BIO_printf(bio_err,
                   "-descert      encrypt PKCS#12 certificates with triple DES (default RC2-40)\n");
        BIO_printf(bio_err,
                   "-certpbe alg  specify certificate PBE algorithm (default RC2-40)\n");
        BIO_printf(bio_err,
                   "-keypbe alg   specify private key PBE algorithm (default 3DES)\n");
        BIO_printf(bio_err,
                   "-macalg alg   digest algorithm used in MAC (default SHA1)\n");
        BIO_printf(bio_err, "-keyex        set MS key exchange type\n");
        BIO_printf(bio_err, "-keysig       set MS key signature type\n");
        BIO_printf(bio_err,
                   "-password p   set import/export password source\n");
        BIO_printf(bio_err, "-passin p     input file pass phrase source\n");
        BIO_printf(bio_err, "-passout p    output file pass phrase source\n");
# ifndef OPENSSL_NO_ENGINE
        BIO_printf(bio_err,
                   "-engine e     use engine e, possibly a hardware device.\n");
# endif
        BIO_printf(bio_err, "-rand file%cfile%c...\n", LIST_SEPARATOR_CHAR,
                   LIST_SEPARATOR_CHAR);
        BIO_printf(bio_err,
                   "              load the file (or the files in the directory) into\n");
        BIO_printf(bio_err, "              the random number generator\n");
        BIO_printf(bio_err, "-CSP name     Microsoft CSP name\n");
        BIO_printf(bio_err,
                   "-LMK          Add local machine keyset attribute to private key\n");
        goto end;
    }
    e = setup_engine(bio_err, engine, 0);

    if (passarg) {
        if (export_cert)
            passargout = passarg;
        else
            passargin = passarg;
    }

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

    if (!cpass) {
        if (export_cert)
            cpass = passout;
        else
            cpass = passin;
    }

    if (cpass) {
        mpass = cpass;
        noprompt = 1;
    } else {
        cpass = pass;
        mpass = macpass;
    }

    if (export_cert || inrand) {
        app_RAND_load_file(NULL, bio_err, (inrand != NULL));
        if (inrand != NULL)
            BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
                       app_RAND_load_files(inrand));
    }
    ERR_load_crypto_strings();

# ifdef CRYPTO_MDEBUG
    CRYPTO_push_info("read files");
# endif

    if (!infile)
        in = BIO_new_fp(stdin, BIO_NOCLOSE);
    else
        in = BIO_new_file(infile, "rb");
    if (!in) {
        BIO_printf(bio_err, "Error opening input file %s\n",
                   infile ? infile : "<stdin>");
        perror(infile);
        goto end;
    }
# ifdef CRYPTO_MDEBUG
    CRYPTO_pop_info();
    CRYPTO_push_info("write files");
# endif

    if (!outfile) {
        out = BIO_new_fp(stdout, BIO_NOCLOSE);
# ifdef OPENSSL_SYS_VMS
        {
            BIO *tmpbio = BIO_new(BIO_f_linebuffer());
            out = BIO_push(tmpbio, out);
        }
# endif
    } else
        out = BIO_new_file(outfile, "wb");
    if (!out) {
        BIO_printf(bio_err, "Error opening output file %s\n",
                   outfile ? outfile : "<stdout>");
        perror(outfile);
        goto end;
    }
    if (twopass) {
# ifdef CRYPTO_MDEBUG
        CRYPTO_push_info("read MAC password");
# endif
        if (EVP_read_pw_string
            (macpass, sizeof macpass, "Enter MAC Password:"******"Can't read Password\n");
            goto end;
        }
# ifdef CRYPTO_MDEBUG
        CRYPTO_pop_info();
# endif
    }

    if (export_cert) {
        EVP_PKEY *key = NULL;
        X509 *ucert = NULL, *x = NULL;
        STACK_OF(X509) *certs = NULL;
        const EVP_MD *macmd = NULL;
        unsigned char *catmp = NULL;
        int i;

        if ((options & (NOCERTS | NOKEYS)) == (NOCERTS | NOKEYS)) {
            BIO_printf(bio_err, "Nothing to do!\n");
            goto export_end;
        }

        if (options & NOCERTS)
            chain = 0;

# ifdef CRYPTO_MDEBUG
        CRYPTO_push_info("process -export_cert");
        CRYPTO_push_info("reading private key");
# endif
        if (!(options & NOKEYS)) {
            key = load_key(bio_err, keyname ? keyname : infile,
                           FORMAT_PEM, 1, passin, e, "private key");
            if (!key)
                goto export_end;
        }
# ifdef CRYPTO_MDEBUG
        CRYPTO_pop_info();
        CRYPTO_push_info("reading certs from input");
# endif

        /* Load in all certs in input file */
        if (!(options & NOCERTS)) {
            certs = load_certs(bio_err, infile, FORMAT_PEM, NULL, e,
                               "certificates");
            if (!certs)
                goto export_end;

            if (key) {
                /* Look for matching private key */
                for (i = 0; i < sk_X509_num(certs); i++) {
                    x = sk_X509_value(certs, i);
                    if (X509_check_private_key(x, key)) {
                        ucert = x;
                        /* Zero keyid and alias */
                        X509_keyid_set1(ucert, NULL, 0);
                        X509_alias_set1(ucert, NULL, 0);
                        /* Remove from list */
                        (void)sk_X509_delete(certs, i);
                        break;
                    }
                }
                if (!ucert) {
                    BIO_printf(bio_err,
                               "No certificate matches private key\n");
                    goto export_end;
                }
            }

        }
# ifdef CRYPTO_MDEBUG
        CRYPTO_pop_info();
        CRYPTO_push_info("reading certs from input 2");
# endif

        /* Add any more certificates asked for */
        if (certfile) {
            STACK_OF(X509) *morecerts = NULL;
            if (!(morecerts = load_certs(bio_err, certfile, FORMAT_PEM,
                                         NULL, e,
                                         "certificates from certfile")))
                goto export_end;
            while (sk_X509_num(morecerts) > 0)
                sk_X509_push(certs, sk_X509_shift(morecerts));
            sk_X509_free(morecerts);
        }
# ifdef CRYPTO_MDEBUG
        CRYPTO_pop_info();
        CRYPTO_push_info("reading certs from certfile");
# endif

# ifdef CRYPTO_MDEBUG
        CRYPTO_pop_info();
        CRYPTO_push_info("building chain");
# endif

        /* If chaining get chain from user cert */
        if (chain) {
            int vret;
            STACK_OF(X509) *chain2;
            X509_STORE *store = X509_STORE_new();
            if (!store) {
                BIO_printf(bio_err, "Memory allocation error\n");
                goto export_end;
            }
            if (!X509_STORE_load_locations(store, CAfile, CApath))
                X509_STORE_set_default_paths(store);

            vret = get_cert_chain(ucert, store, &chain2);
            X509_STORE_free(store);

            if (vret == X509_V_OK) {
                /* Exclude verified certificate */
                for (i = 1; i < sk_X509_num(chain2); i++)
                    sk_X509_push(certs, sk_X509_value(chain2, i));
                /* Free first certificate */
                X509_free(sk_X509_value(chain2, 0));
                sk_X509_free(chain2);
            } else {
                if (vret != X509_V_ERR_UNSPECIFIED)
                    BIO_printf(bio_err, "Error %s getting chain.\n",
                               X509_verify_cert_error_string(vret));
                else
                    ERR_print_errors(bio_err);
                goto export_end;
            }
        }

        /* Add any CA names */

        for (i = 0; i < sk_OPENSSL_STRING_num(canames); i++) {
            catmp = (unsigned char *)sk_OPENSSL_STRING_value(canames, i);
            X509_alias_set1(sk_X509_value(certs, i), catmp, -1);
        }

        if (csp_name && key)
            EVP_PKEY_add1_attr_by_NID(key, NID_ms_csp_name,
                                      MBSTRING_ASC, (unsigned char *)csp_name,
                                      -1);

        if (add_lmk && key)
            EVP_PKEY_add1_attr_by_NID(key, NID_LocalKeySet, 0, NULL, -1);

# ifdef CRYPTO_MDEBUG
        CRYPTO_pop_info();
        CRYPTO_push_info("reading password");
# endif

        if (!noprompt &&
            EVP_read_pw_string(pass, sizeof pass, "Enter Export Password:"******"Can't read Password\n");
            goto export_end;
        }
        if (!twopass)
            BUF_strlcpy(macpass, pass, sizeof macpass);

# ifdef CRYPTO_MDEBUG
        CRYPTO_pop_info();
        CRYPTO_push_info("creating PKCS#12 structure");
# endif

        p12 = PKCS12_create(cpass, name, key, ucert, certs,
                            key_pbe, cert_pbe, iter, -1, keytype);

        if (!p12) {
            ERR_print_errors(bio_err);
            goto export_end;
        }

        if (macalg) {
            macmd = EVP_get_digestbyname(macalg);
            if (!macmd) {
                BIO_printf(bio_err, "Unknown digest algorithm %s\n", macalg);
            }
        }

        if (maciter != -1)
            PKCS12_set_mac(p12, mpass, -1, NULL, 0, maciter, macmd);

# ifdef CRYPTO_MDEBUG
        CRYPTO_pop_info();
        CRYPTO_push_info("writing pkcs12");
# endif

        i2d_PKCS12_bio(out, p12);

        ret = 0;

 export_end:
# ifdef CRYPTO_MDEBUG
        CRYPTO_pop_info();
        CRYPTO_pop_info();
        CRYPTO_push_info("process -export_cert: freeing");
# endif

        if (key)
            EVP_PKEY_free(key);
        if (certs)
            sk_X509_pop_free(certs, X509_free);
        if (ucert)
            X509_free(ucert);

# ifdef CRYPTO_MDEBUG
        CRYPTO_pop_info();
# endif
        goto end;

    }

    if (!(p12 = d2i_PKCS12_bio(in, NULL))) {
        ERR_print_errors(bio_err);
        goto end;
    }
# ifdef CRYPTO_MDEBUG
    CRYPTO_push_info("read import password");
# endif
    if (!noprompt
        && EVP_read_pw_string(pass, sizeof pass, "Enter Import Password:"******"Can't read Password\n");
        goto end;
    }
# ifdef CRYPTO_MDEBUG
    CRYPTO_pop_info();
# endif

    if (!twopass)
        BUF_strlcpy(macpass, pass, sizeof macpass);

    if ((options & INFO) && p12->mac)
        BIO_printf(bio_err, "MAC Iteration %ld\n",
                   p12->mac->iter ? ASN1_INTEGER_get(p12->mac->iter) : 1);
    if (macver) {
# ifdef CRYPTO_MDEBUG
        CRYPTO_push_info("verify MAC");
# endif
        /* If we enter empty password try no password first */
        if (!mpass[0] && PKCS12_verify_mac(p12, NULL, 0)) {
            /* If mac and crypto pass the same set it to NULL too */
            if (!twopass)
                cpass = NULL;
        } else if (!PKCS12_verify_mac(p12, mpass, -1)) {
            BIO_printf(bio_err, "Mac verify error: invalid password?\n");
            ERR_print_errors(bio_err);
            goto end;
        }
        BIO_printf(bio_err, "MAC verified OK\n");
# ifdef CRYPTO_MDEBUG
        CRYPTO_pop_info();
# endif
    }
# ifdef CRYPTO_MDEBUG
    CRYPTO_push_info("output keys and certificates");
# endif
    if (!dump_certs_keys_p12(out, p12, cpass, -1, options, passout)) {
        BIO_printf(bio_err, "Error outputting keys and certificates\n");
        ERR_print_errors(bio_err);
        goto end;
    }
# ifdef CRYPTO_MDEBUG
    CRYPTO_pop_info();
# endif
    ret = 0;
 end:
    if (p12)
        PKCS12_free(p12);
    if (export_cert || inrand)
        app_RAND_write_file(NULL, bio_err);
# ifdef CRYPTO_MDEBUG
    CRYPTO_remove_all_info();
# endif
    release_engine(e);
    BIO_free(in);
    BIO_free_all(out);
    if (canames)
        sk_OPENSSL_STRING_free(canames);
    if (passin)
        OPENSSL_free(passin);
    if (passout)
        OPENSSL_free(passout);
    apps_shutdown();
    OPENSSL_EXIT(ret);
}
Example #11
0
 * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the OpenSSL license (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

#include <stdio.h>
#include "internal/cryptlib.h"
#include <openssl/objects.h>
#include <openssl/ts.h>
#include <openssl/pkcs7.h>
#include "ts_lcl.h"

static int ts_verify_cert(X509_STORE *store, STACK_OF(X509) *untrusted,
                          X509 *signer, STACK_OF(X509) **chain);
static int ts_check_signing_certs(PKCS7_SIGNER_INFO *si,
                                  STACK_OF(X509) *chain);
static ESS_SIGNING_CERT *ess_get_signing_cert(PKCS7_SIGNER_INFO *si);
static int ts_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert);
static int ts_issuer_serial_cmp(ESS_ISSUER_SERIAL *is, X509 *cert);
static int int_ts_RESP_verify_token(TS_VERIFY_CTX *ctx,
                                    PKCS7 *token, TS_TST_INFO *tst_info);
static int ts_check_status_info(TS_RESP *response);
static char *ts_get_status_text(STACK_OF(ASN1_UTF8STRING) *text);
static int ts_check_policy(const ASN1_OBJECT *req_oid,
                           const TS_TST_INFO *tst_info);
static int ts_compute_imprint(BIO *data, TS_TST_INFO *tst_info,
                              X509_ALGOR **md_alg,
                              unsigned char **imprint, unsigned *imprint_len);
Example #12
0
# include <openssl/err.h>
# include <openssl/pem.h>
# include <openssl/pkcs12.h>

# define PROG pkcs12_main

const EVP_CIPHER *enc;

# define NOKEYS          0x1
# define NOCERTS         0x2
# define INFO            0x4
# define CLCERTS         0x8
# define CACERTS         0x10

static int get_cert_chain(X509 *cert, X509_STORE *store,
                          STACK_OF(X509) **chain);
int dump_certs_keys_p12(BIO *out, PKCS12 *p12, char *pass, int passlen,
                        int options, char *pempass);
int dump_certs_pkeys_bags(BIO *out, STACK_OF(PKCS12_SAFEBAG) *bags,
                          char *pass, int passlen, int options,
                          char *pempass);
int dump_certs_pkeys_bag(BIO *out, PKCS12_SAFEBAG *bags, char *pass,
                         int passlen, int options, char *pempass);
int print_attribs(BIO *out, STACK_OF(X509_ATTRIBUTE) *attrlst,
                  const char *name);
void hex_prin(BIO *out, unsigned char *buf, int len);
int alg_print(BIO *x, X509_ALGOR *alg);
int cert_load(BIO *in, STACK_OF(X509) *sk);
static int set_pbe(BIO *err, int *ppbe, const char *str);

int MAIN(int, char **);
Example #13
0
int main(int argc, char **argv)
{
    FILE *fp;
    EVP_PKEY *pkey = NULL;
    X509 *cert = NULL;
    STACK_OF(X509) *ca = NULL;
    PKCS12 *p12 = NULL;
    char *name = NULL;
    int i, ret = EXIT_FAILURE;

    if (argc != 4) {
        fprintf(stderr, "Usage: pkread p12file password opfile\n");
        exit(EXIT_FAILURE);
    }

    if ((fp = fopen(argv[1], "rb")) == NULL) {
        fprintf(stderr, "Error opening file %s\n", argv[1]);
        exit(EXIT_FAILURE);
    }
    p12 = d2i_PKCS12_fp(fp, NULL);
    fclose(fp);
    if (p12 == NULL) {
        fprintf(stderr, "Error reading PKCS#12 file\n");
        ERR_print_errors_fp(stderr);
        goto err;
    }
    if (!PKCS12_parse(p12, argv[2], &pkey, &cert, &ca)) {
        fprintf(stderr, "Error parsing PKCS#12 file\n");
        ERR_print_errors_fp(stderr);
        goto err;
    }
    name = find_friendly_name(p12);
    PKCS12_free(p12);
    if ((fp = fopen(argv[3], "w")) == NULL) {
        fprintf(stderr, "Error opening file %s\n", argv[1]);
        goto err;
    }
    if (name != NULL)
        fprintf(fp, "***Friendly Name***\n%s\n", name);
    if (pkey != NULL) {
        fprintf(fp, "***Private Key***\n");
        PEM_write_PrivateKey(fp, pkey, NULL, NULL, 0, NULL, NULL);
    }
    if (cert != NULL) {
        fprintf(fp, "***User Certificate***\n");
        PEM_write_X509_AUX(fp, cert);
    }
    if (ca != NULL && sk_X509_num(ca) > 0) {
        fprintf(fp, "***Other Certificates***\n");
        for (i = 0; i < sk_X509_num(ca); i++)
            PEM_write_X509_AUX(fp, sk_X509_value(ca, i));
    }
    fclose(fp);

    ret = EXIT_SUCCESS;

 err:
    OPENSSL_free(name);
    X509_free(cert);
    EVP_PKEY_free(pkey);
    sk_X509_pop_free(ca, X509_free);

    return ret;
}
Example #14
0
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * ([email protected]).  This product includes software written by Tim
 * Hudson ([email protected]).
 *
 */

#include <openssl/ocsp.h>
#include <openssl/err.h>
#include <string.h>

static int ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, STACK_OF(X509) *certs,
				X509_STORE *st, unsigned long flags);
static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id);
static int ocsp_check_issuer(OCSP_BASICRESP *bs, STACK_OF(X509) *chain, unsigned long flags);
static int ocsp_check_ids(STACK_OF(OCSP_SINGLERESP) *sresp, OCSP_CERTID **ret);
static int ocsp_match_issuerid(X509 *cert, OCSP_CERTID *cid, STACK_OF(OCSP_SINGLERESP) *sresp);
static int ocsp_check_delegated(X509 *x, int flags);
static int ocsp_req_find_signer(X509 **psigner, OCSP_REQUEST *req, X509_NAME *nm, STACK_OF(X509) *certs,
				X509_STORE *st, unsigned long flags);

/* Verify a basic response message */

int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs,
				X509_STORE *st, unsigned long flags)
	{
	X509 *signer, *x;
Example #15
0
int
ssl_check_subject_altname(X509 *cert, char *host)
{
	STACK_OF(GENERAL_NAME)	*altname_stack = NULL;
	union { struct in_addr ip4; struct in6_addr ip6; } addrbuf;
	int	addrlen, type;
	int	count, i;
	int	rv = -1;

	altname_stack =
	    X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
	if (altname_stack == NULL)
		return -1;

	if (inet_pton(AF_INET, host, &addrbuf) == 1) {
		type = GEN_IPADD;
		addrlen = 4;
	} else if (inet_pton(AF_INET6, host, &addrbuf) == 1) {
		type = GEN_IPADD;
		addrlen = 16;
	} else
		type = GEN_DNS;

	count = sk_GENERAL_NAME_num(altname_stack);
	for (i = 0; i < count; i++) {
		GENERAL_NAME	*altname;

		altname = sk_GENERAL_NAME_value(altname_stack, i);

		if (altname->type != type)
			continue;

		if (type == GEN_DNS) {
			unsigned char	*data;
			int		 format;

			format = ASN1_STRING_type(altname->d.dNSName);
			if (format == V_ASN1_IA5STRING) {
				data = ASN1_STRING_data(altname->d.dNSName);

				if (ASN1_STRING_length(altname->d.dNSName) !=
				    (int)strlen(data)) {
					fprintf(ttyout, "%s: NUL byte in "
					    "subjectAltName, probably a "
					    "malicious certificate.\n",
					    getprogname());
					rv = -2;
					break;
				}

				if (ssl_match_hostname(data, host) == 0) {
					rv = 0;
					break;
				}
			} else
				fprintf(ttyout, "%s: unhandled subjectAltName "
				    "dNSName encoding (%d)\n", getprogname(),
				    format);

		} else if (type == GEN_IPADD) {
			unsigned char	*data;
			int		 datalen;

			datalen = ASN1_STRING_length(altname->d.iPAddress);
			data = ASN1_STRING_data(altname->d.iPAddress);

			if (datalen == addrlen &&
			    memcmp(data, &addrbuf, addrlen) == 0) {
				rv = 0;
				break;
			}
		}
	}

	sk_GENERAL_NAME_free(altname_stack);
	return rv;
}
Example #16
0
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

#include <stdio.h>
#include "internal/cryptlib.h"
#include <openssl/conf.h>
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/x509v3.h>
#include "ext_dat.h"

static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
                                                 AUTHORITY_KEYID *akeyid,
                                                 STACK_OF(CONF_VALUE)
                                                 *extlist);
static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
                                            X509V3_CTX *ctx,
                                            STACK_OF(CONF_VALUE) *values);

const X509V3_EXT_METHOD v3_akey_id = {
    NID_authority_key_identifier,
    X509V3_EXT_MULTILINE, ASN1_ITEM_ref(AUTHORITY_KEYID),
    0, 0, 0, 0,
    0, 0,
    (X509V3_EXT_I2V) i2v_AUTHORITY_KEYID,
    (X509V3_EXT_V2I)v2i_AUTHORITY_KEYID,
    0, 0,
    NULL
};
int main(int argc, char **argv)
	{
	BIO *in = NULL, *out = NULL, *tbio = NULL;
	X509 *rcert = NULL;
	STACK_OF(X509) *recips = NULL;
	CMS_ContentInfo *cms = NULL;
	int ret = 1;

	/*
	 * On OpenSSL 1.0.0 and later only:
	 * for streaming set CMS_STREAM
	 */
	int flags = CMS_STREAM;

	OpenSSL_add_all_algorithms();
	ERR_load_crypto_strings();

	/* Read in recipient certificate */
	tbio = BIO_new_file("signer.pem", "r");

	if (!tbio)
		goto err;

	rcert = PEM_read_bio_X509(tbio, NULL, 0, NULL);

	if (!rcert)
		goto err;

	/* Create recipient STACK and add recipient cert to it */
	recips = sk_X509_new_null();

	if (!recips || !sk_X509_push(recips, rcert))
		goto err;

	/* sk_X509_pop_free will free up recipient STACK and its contents
	 * so set rcert to NULL so it isn't freed up twice.
	 */
	rcert = NULL;

	/* Open content being encrypted */

	in = BIO_new_file("encr.txt", "r");

	if (!in)
		goto err;

	/* encrypt content */
	cms = CMS_encrypt(recips, in, EVP_des_ede3_cbc(), flags);

	if (!cms)
		goto err;

	out = BIO_new_file("smencr.txt", "w");
	if (!out)
		goto err;

	/* Write out S/MIME message */
	if (!SMIME_write_CMS(out, cms, in, flags))
		goto err;

	ret = 0;

	err:

	if (ret)
		{
		fprintf(stderr, "Error Encrypting Data\n");
		ERR_print_errors_fp(stderr);
		}

	if (cms)
		CMS_ContentInfo_free(cms);
	if (rcert)
		X509_free(rcert);
	if (recips)
		sk_X509_pop_free(recips, X509_free);

	if (in)
		BIO_free(in);
	if (out)
		BIO_free(out);
	if (tbio)
		BIO_free(tbio);

	return ret;

	}
Example #18
0
static int test_uchar_stack(void)
{
    static const unsigned char v[] = { 1, 3, 7, 5, 255, 0 };
    const int n = OSSL_NELEM(v);
    STACK_OF(uchar) *s = sk_uchar_new(&uchar_compare), *r = NULL;
    int i;
    int testresult = 0;

    /* unshift and num */
    for (i = 0; i < n; i++) {
        if (!TEST_int_eq(sk_uchar_num(s), i)) {
            TEST_info("uchar stack size %d", i);
            goto end;
        }
        sk_uchar_unshift(s, v + i);
    }
    if (!TEST_int_eq(sk_uchar_num(s), n))
        goto end;

    /* dup */
    r = sk_uchar_dup(s);
    if (!TEST_int_eq(sk_uchar_num(r), n))
        goto end;
    sk_uchar_sort(r);

    /* pop */
    for (i = 0; i < n; i++)
        if (!TEST_ptr_eq(sk_uchar_pop(s), v + i)) {
            TEST_info("uchar pop %d", i);
            goto end;
        }

    /* free -- we rely on the debug malloc to detect leakage here */
    sk_uchar_free(s);
    s = NULL;

    /* dup again */
    if (!TEST_int_eq(sk_uchar_num(r), n))
        goto end;

    /* zero */
    sk_uchar_zero(r);
    if (!TEST_int_eq(sk_uchar_num(r), 0))
        goto end;

    /* insert */
    sk_uchar_insert(r, v, 0);
    sk_uchar_insert(r, v + 2, -1);
    sk_uchar_insert(r, v + 1, 1);
    for (i = 0; i < 3; i++)
        if (!TEST_ptr_eq(sk_uchar_value(r, i), v + i)) {
            TEST_info("uchar insert %d", i);
            goto end;
        }

    /* delete */
    if (!TEST_ptr_null(sk_uchar_delete(r, 12)))
        goto end;
    if (!TEST_ptr_eq(sk_uchar_delete(r, 1), v + 1))
        goto end;

    /* set */
    sk_uchar_set(r, 1, v + 1);
    for (i = 0; i < 2; i++)
        if (!TEST_ptr_eq(sk_uchar_value(r, i), v + i)) {
            TEST_info("uchar set %d", i);
            goto end;
        }

    testresult = 1;
end:
    sk_uchar_free(r);
    sk_uchar_free(s);
    return testresult;
}
Example #19
0
bool SSLSocket::enableCrypto(bool activate /* = true */) {
  if (activate && !m_data->m_ssl_active) {
    double timeout = m_data->m_connect_timeout;
    bool blocked = m_data->m_is_blocked;
    if (!m_data->m_state_set) {
      if (m_data->m_client) {
        SSL_set_connect_state(m_data->m_handle);
      } else {
        SSL_set_accept_state(m_data->m_handle);
      }
      m_data->m_state_set = true;
    }

    if (m_data->m_client && setBlocking(false)) {
      m_data->m_is_blocked = false;
    }

    int n;
    bool retry = true;
    do {
      if (m_data->m_client) {
        struct timeval tvs, tve;
        struct timezone tz;

        gettimeofday(&tvs, &tz);
        n = SSL_connect(m_data->m_handle);
        gettimeofday(&tve, &tz);

        timeout -= (tve.tv_sec + (double) tve.tv_usec / 1000000) -
          (tvs.tv_sec + (double) tvs.tv_usec / 1000000);
        if (timeout < 0) {
          raise_warning("SSL: connection timeout");
          return -1;
        }
      } else {
        n = SSL_accept(m_data->m_handle);
      }

      if (n <= 0) {
        retry = handleError(n, true);
      } else {
        break;
      }
    } while (retry);

    if (m_data->m_client &&
        m_data->m_is_blocked != blocked &&
        setBlocking(blocked)) {
      m_data->m_is_blocked = blocked;
    }

    if (n == 1) {
      X509 *peer_cert = SSL_get_peer_certificate(m_data->m_handle);
      if (!applyVerificationPolicy(peer_cert)) {
        SSL_shutdown(m_data->m_handle);
      } else {
        m_data->m_ssl_active = true;

        /* allow the script to capture the peer cert
         * and/or the certificate chain */
        if (m_context[s_capture_peer_cert].toBoolean()) {
          m_context.set(s_peer_certificate,
                        Variant(makeSmartPtr<Certificate>(peer_cert)));
          peer_cert = nullptr;
        }

        if (m_context[s_capture_peer_cert_chain].toBoolean()) {
          Array arr;
          STACK_OF(X509) *chain = SSL_get_peer_cert_chain(m_data->m_handle);
          if (chain) {
            for (int i = 0; i < sk_X509_num(chain); i++) {
              X509 *mycert = X509_dup(sk_X509_value(chain, i));
              arr.append(Variant(makeSmartPtr<Certificate>(mycert)));
            }
          }
          m_context.set(s_peer_certificate_chain, arr);
        }
      }

      if (peer_cert) {
        X509_free(peer_cert);
      }
    } else  {
      n = errno == EAGAIN ? 0 : -1;
    }

    return n >= 0;

  } else if (!activate && m_data->m_ssl_active) {
    /* deactivate - common for server/client */
    SSL_shutdown(m_data->m_handle);
    m_data->m_ssl_active = false;
  }
  return true;
}
Example #20
0
static int test_SS_stack(void)
{
    STACK_OF(SS) *s = sk_SS_new_null();
    STACK_OF(SS) *r = NULL;
    SS *v[10], *p;
    const int n = OSSL_NELEM(v);
    int i;
    int testresult = 0;

    /* allocate and push */
    for (i = 0; i < n; i++) {
        v[i] = OPENSSL_malloc(sizeof(*v[i]));

        if (!TEST_ptr(v[i]))
            goto end;
        v[i]->n = i;
        v[i]->c = 'A' + i;
        if (!TEST_int_eq(sk_SS_num(s), i)) {
            TEST_info("SS stack size %d", i);
            goto end;
        }
        sk_SS_push(s, v[i]);
    }
    if (!TEST_int_eq(sk_SS_num(s), n))
        goto end;

    /* deepcopy */
    r = sk_SS_deep_copy(s, &SS_copy, &SS_free);
    if (!TEST_ptr(r))
        goto end;
    for (i = 0; i < n; i++) {
        p = sk_SS_value(r, i);
        if (!TEST_ptr_ne(p, v[i])) {
            TEST_info("SS deepcopy non-copy %d", i);
            goto end;
        }
        if (!TEST_int_eq(p->n, v[i]->n)) {
            TEST_info("test SS deepcopy int %d", i);
            goto end;
        }
        if (!TEST_char_eq(p->c, v[i]->c)) {
            TEST_info("SS deepcopy char %d", i);
            goto end;
        }
    }

    /* pop_free - we rely on the malloc debug to catch the leak */
    sk_SS_pop_free(r, &SS_free);
    r = NULL;

    /* delete_ptr */
    p = sk_SS_delete_ptr(s, v[3]);
    if (!TEST_ptr(p))
        goto end;
    SS_free(p);
    if (!TEST_int_eq(sk_SS_num(s), n - 1))
        goto end;
    for (i = 0; i < n-1; i++)
        if (!TEST_ptr_eq(sk_SS_value(s, i), v[i<3 ? i : 1+i])) {
            TEST_info("SS delete ptr item %d", i);
            goto end;
        }

    testresult = 1;
end:
    sk_SS_pop_free(r, &SS_free);
    sk_SS_pop_free(s, &SS_free);
    return testresult;
}
Example #21
0
    { 1, "Non Repudiation", "nonRepudiation" },
    { 2, "Key Encipherment", "keyEncipherment" },
    { 3, "Data Encipherment", "dataEncipherment" },
    { 4, "Key Agreement", "keyAgreement" },
    { 5, "Certificate Sign", "keyCertSign" },
    { 6, "CRL Sign", "cRLSign" },
    { 7, "Encipher Only", "encipherOnly" },
    { 8, "Decipher Only", "decipherOnly" },
    { -1, NULL, NULL }
};

const X509V3_EXT_METHOD v3_nscert = EXT_BITSTRING(NID_netscape_cert_type, ns_cert_type_table);
const X509V3_EXT_METHOD v3_key_usage = EXT_BITSTRING(NID_key_usage, key_usage_type_table);

STACK_OF(CONF_VALUE) *i2v_ASN1_BIT_STRING(X509V3_EXT_METHOD *method,
                                           ASN1_BIT_STRING *bits, STACK_OF(CONF_VALUE) *ret)
{
    BIT_STRING_BITNAME *bnam;
    for (bnam = method->usr_data; bnam->lname; bnam++) {
        if (ASN1_BIT_STRING_get_bit(bits, bnam->bitnum))
            X509V3_add_value(bnam->lname, NULL, &ret);
    }
    return ret;
}

ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method,
                                     X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
{
    CONF_VALUE *val;
    ASN1_BIT_STRING *bs;
    int i;
Example #22
0
static int test_int_stack(void)
{
    static int v[] = { 1, 2, -4, 16, 999, 1, -173, 1, 9 };
    static int notpresent = -1;
    const int n = OSSL_NELEM(v);
    static struct {
        int value;
        int unsorted;
        int sorted;
        int ex;
    } finds[] = {
        { 2,    1,  5,  5   },
        { 9,    7,  6,  6   },
        { -173, 5,  0,  0   },
        { 999,  3,  8,  8   },
        { 0,   -1, -1,  1   }
    };
    const int n_finds = OSSL_NELEM(finds);
    static struct {
        int value;
        int ex;
    } exfinds[] = {
        { 3,    5   },
        { 1000, 8   },
        { 20,   8   },
        { -999, 0   },
        { -5,   0   },
        { 8,    5   }
    };
    const int n_exfinds = OSSL_NELEM(exfinds);
    STACK_OF(sint) *s = sk_sint_new_null();
    int i;
    int testresult = 0;

    /* Check push and num */
    for (i = 0; i < n; i++) {
        if (!TEST_int_eq(sk_sint_num(s), i)) {
            TEST_info("int stack size %d", i);
            goto end;
        }
        sk_sint_push(s, v + i);
    }
    if (!TEST_int_eq(sk_sint_num(s), n))
        goto end;

    /* check the values */
    for (i = 0; i < n; i++)
        if (!TEST_ptr_eq(sk_sint_value(s, i), v + i)) {
            TEST_info("int value %d", i);
            goto end;
        }

    /* find unsorted -- the pointers are compared */
    for (i = 0; i < n_finds; i++) {
        int *val = (finds[i].unsorted == -1) ? &notpresent
                                             : v + finds[i].unsorted;

        if (!TEST_int_eq(sk_sint_find(s, val), finds[i].unsorted)) {
            TEST_info("int unsorted find %d", i);
            goto end;
        }
    }

    /* find_ex unsorted */
    for (i = 0; i < n_finds; i++) {
        int *val = (finds[i].unsorted == -1) ? &notpresent
                                             : v + finds[i].unsorted;

        if (!TEST_int_eq(sk_sint_find_ex(s, val), finds[i].unsorted)) {
            TEST_info("int unsorted find_ex %d", i);
            goto end;
        }
    }

    /* sorting */
    if (!TEST_false(sk_sint_is_sorted(s)))
        goto end;
    sk_sint_set_cmp_func(s, &int_compare);
    sk_sint_sort(s);
    if (!TEST_true(sk_sint_is_sorted(s)))
        goto end;

    /* find sorted -- the value is matched so we don't need to locate it */
    for (i = 0; i < n_finds; i++)
        if (!TEST_int_eq(sk_sint_find(s, &finds[i].value), finds[i].sorted)) {
            TEST_info("int sorted find %d", i);
            goto end;
        }

    /* find_ex sorted */
    for (i = 0; i < n_finds; i++)
        if (!TEST_int_eq(sk_sint_find_ex(s, &finds[i].value), finds[i].ex)) {
            TEST_info("int sorted find_ex present %d", i);
            goto end;
        }
    for (i = 0; i < n_exfinds; i++)
        if (!TEST_int_eq(sk_sint_find_ex(s, &exfinds[i].value), exfinds[i].ex)){
            TEST_info("int sorted find_ex absent %d", i);
            goto end;
        }

    /* shift */
    if (!TEST_ptr_eq(sk_sint_shift(s), v + 6))
        goto end;

    testresult = 1;
end:
    sk_sint_free(s);
    return testresult;
}
Example #23
0
        /*
         * Now we know that a key and cert have been set against the SSL
         * context
         */
        if (!SSL_CTX_check_private_key(ctx)) {
            BIO_printf(bio_err,
                       "Private key does not match the certificate public key\n");
            return (0);
        }
    }
    return (1);
}

int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key,
                       STACK_OF(X509) *chain, int build_chain)
{
    int chflags = chain ? SSL_BUILD_CHAIN_FLAG_CHECK : 0;
    if (cert == NULL)
        return 1;
    if (SSL_CTX_use_certificate(ctx, cert) <= 0) {
        BIO_printf(bio_err, "error setting certificate\n");
        ERR_print_errors(bio_err);
        return 0;
    }

    if (SSL_CTX_use_PrivateKey(ctx, key) <= 0) {
        BIO_printf(bio_err, "error setting private key\n");
        ERR_print_errors(bio_err);
        return 0;
    }
Example #24
0
int dgst_main(int argc, char **argv)
{
    BIO *in = NULL, *inp, *bmd = NULL, *out = NULL;
    ENGINE *e = NULL, *impl = NULL;
    EVP_PKEY *sigkey = NULL;
    STACK_OF(OPENSSL_STRING) *sigopts = NULL, *macopts = NULL;
    char *hmac_key = NULL;
    char *mac_name = NULL;
    char *passinarg = NULL, *passin = NULL;
    const EVP_MD *md = NULL, *m;
    const char *outfile = NULL, *keyfile = NULL, *prog = NULL;
    const char *sigfile = NULL, *randfile = NULL;
    OPTION_CHOICE o;
    int separator = 0, debug = 0, keyform = FORMAT_PEM, siglen = 0;
    int i, ret = 1, out_bin = -1, want_pub = 0, do_verify =
        0, non_fips_allow = 0;
    unsigned char *buf = NULL, *sigbuf = NULL;
    int engine_impl = 0;

    prog = opt_progname(argv[0]);
    if ((buf = (unsigned char *)OPENSSL_malloc(BUFSIZE)) == NULL) {
        BIO_printf(bio_err, "%s: out of memory\n", prog);
        goto end;
    }
    md = EVP_get_digestbyname(prog);

    prog = opt_init(argc, argv, dgst_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(dgst_options);
            ret = 0;
            goto end;
        case OPT_C:
            separator = 1;
            break;
        case OPT_R:
            separator = 2;
            break;
        case OPT_RAND:
            randfile = opt_arg();
            break;
        case OPT_OUT:
            outfile = opt_arg();
            break;
        case OPT_SIGN:
            keyfile = opt_arg();
            break;
        case OPT_PASSIN:
            passinarg = opt_arg();
            break;
        case OPT_VERIFY:
            keyfile = opt_arg();
            want_pub = do_verify = 1;
            break;
        case OPT_PRVERIFY:
            keyfile = opt_arg();
            do_verify = 1;
            break;
        case OPT_SIGNATURE:
            sigfile = opt_arg();
            break;
        case OPT_KEYFORM:
            if (!opt_format(opt_arg(), OPT_FMT_ANY, &keyform))
                goto opthelp;
            break;
        case OPT_ENGINE:
            e = setup_engine(opt_arg(), 0);
            break;
        case OPT_ENGINE_IMPL:
            engine_impl = 1;
            break;
        case OPT_HEX:
            out_bin = 0;
            break;
        case OPT_BINARY:
            out_bin = 1;
            break;
        case OPT_DEBUG:
            debug = 1;
            break;
        case OPT_FIPS_FINGERPRINT:
            hmac_key = "etaonrishdlcupfm";
            break;
        case OPT_NON_FIPS_ALLOW:
            non_fips_allow = 1;
            break;
        case OPT_HMAC:
            hmac_key = opt_arg();
            break;
        case OPT_MAC:
            mac_name = opt_arg();
            break;
        case OPT_SIGOPT:
            if (!sigopts)
                sigopts = sk_OPENSSL_STRING_new_null();
            if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, opt_arg()))
                goto opthelp;
            break;
        case OPT_MACOPT:
            if (!macopts)
                macopts = sk_OPENSSL_STRING_new_null();
            if (!macopts || !sk_OPENSSL_STRING_push(macopts, opt_arg()))
                goto opthelp;
            break;
        case OPT_DIGEST:
            if (!opt_md(opt_unknown(), &m))
                goto opthelp;
            md = m;
            break;
        }
    }
    argc = opt_num_rest();
    argv = opt_rest();

    if (do_verify && !sigfile) {
        BIO_printf(bio_err,
                   "No signature to verify: use the -signature option\n");
        goto end;
    }
    if (engine_impl)
        impl = e;

    in = BIO_new(BIO_s_file());
    bmd = BIO_new(BIO_f_md());
    if ((in == NULL) || (bmd == NULL)) {
        ERR_print_errors(bio_err);
        goto end;
    }

    if (debug) {
        BIO_set_callback(in, BIO_debug_callback);
        /* needed for windows 3.1 */
        BIO_set_callback_arg(in, (char *)bio_err);
    }

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

    if (out_bin == -1) {
        if (keyfile)
            out_bin = 1;
        else
            out_bin = 0;
    }

    if (randfile)
        app_RAND_load_file(randfile, 0);

    out = bio_open_default(outfile, out_bin ? "wb" : "w");
    if (out == NULL)
        goto end;

    if ((! !mac_name + ! !keyfile + ! !hmac_key) > 1) {
        BIO_printf(bio_err, "MAC and Signing key cannot both be specified\n");
        goto end;
    }

    if (keyfile) {
        if (want_pub)
            sigkey = load_pubkey(keyfile, keyform, 0, NULL, e, "key file");
        else
            sigkey = load_key(keyfile, keyform, 0, passin, e, "key file");
        if (!sigkey) {
            /*
             * load_[pub]key() has already printed an appropriate message
             */
            goto end;
        }
    }

    if (mac_name) {
        EVP_PKEY_CTX *mac_ctx = NULL;
        int r = 0;
        if (!init_gen_str(&mac_ctx, mac_name, impl, 0))
            goto mac_end;
        if (macopts) {
            char *macopt;
            for (i = 0; i < sk_OPENSSL_STRING_num(macopts); i++) {
                macopt = sk_OPENSSL_STRING_value(macopts, i);
                if (pkey_ctrl_string(mac_ctx, macopt) <= 0) {
                    BIO_printf(bio_err,
                               "MAC parameter error \"%s\"\n", macopt);
                    ERR_print_errors(bio_err);
                    goto mac_end;
                }
            }
        }
        if (EVP_PKEY_keygen(mac_ctx, &sigkey) <= 0) {
            BIO_puts(bio_err, "Error generating key\n");
            ERR_print_errors(bio_err);
            goto mac_end;
        }
        r = 1;
 mac_end:
        EVP_PKEY_CTX_free(mac_ctx);
        if (r == 0)
            goto end;
    }

    if (non_fips_allow) {
        EVP_MD_CTX *md_ctx;
        BIO_get_md_ctx(bmd, &md_ctx);
        EVP_MD_CTX_set_flags(md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
    }

    if (hmac_key) {
        sigkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, impl,
                                      (unsigned char *)hmac_key, -1);
        if (!sigkey)
            goto end;
    }

    if (sigkey) {
        EVP_MD_CTX *mctx = NULL;
        EVP_PKEY_CTX *pctx = NULL;
        int r;
        if (!BIO_get_md_ctx(bmd, &mctx)) {
            BIO_printf(bio_err, "Error getting context\n");
            ERR_print_errors(bio_err);
            goto end;
        }
        if (do_verify)
            r = EVP_DigestVerifyInit(mctx, &pctx, md, impl, sigkey);
        else
            r = EVP_DigestSignInit(mctx, &pctx, md, impl, sigkey);
        if (!r) {
            BIO_printf(bio_err, "Error setting context\n");
            ERR_print_errors(bio_err);
            goto end;
        }
        if (sigopts) {
            char *sigopt;
            for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++) {
                sigopt = sk_OPENSSL_STRING_value(sigopts, i);
                if (pkey_ctrl_string(pctx, sigopt) <= 0) {
                    BIO_printf(bio_err, "parameter error \"%s\"\n", sigopt);
                    ERR_print_errors(bio_err);
                    goto end;
                }
            }
        }
    }
    /* we use md as a filter, reading from 'in' */
    else {
        EVP_MD_CTX *mctx = NULL;
        if (!BIO_get_md_ctx(bmd, &mctx)) {
            BIO_printf(bio_err, "Error getting context\n");
            ERR_print_errors(bio_err);
            goto end;
        }
        if (md == NULL)
            md = EVP_md5();
        if (!EVP_DigestInit_ex(mctx, md, impl)) {
            BIO_printf(bio_err, "Error setting digest\n");
            ERR_print_errors(bio_err);
            goto end;
        }
    }

    if (sigfile && sigkey) {
        BIO *sigbio = BIO_new_file(sigfile, "rb");
        if (!sigbio) {
            BIO_printf(bio_err, "Error opening signature file %s\n", sigfile);
            ERR_print_errors(bio_err);
            goto end;
        }
        siglen = EVP_PKEY_size(sigkey);
        sigbuf = OPENSSL_malloc(siglen);
        if (!sigbuf) {
            BIO_printf(bio_err, "Out of memory\n");
            goto end;
        }
        siglen = BIO_read(sigbio, sigbuf, siglen);
        BIO_free(sigbio);
        if (siglen <= 0) {
            BIO_printf(bio_err, "Error reading signature file %s\n", sigfile);
            ERR_print_errors(bio_err);
            goto end;
        }
    }
    inp = BIO_push(bmd, in);

    if (md == NULL) {
        EVP_MD_CTX *tctx;
        BIO_get_md_ctx(bmd, &tctx);
        md = EVP_MD_CTX_md(tctx);
    }

    if (argc == 0) {
        BIO_set_fp(in, stdin, BIO_NOCLOSE);
        ret = do_fp(out, buf, inp, separator, out_bin, sigkey, sigbuf,
                    siglen, NULL, NULL, "stdin", bmd);
    } else {
        const char *md_name = NULL, *sig_name = NULL;
        if (!out_bin) {
            if (sigkey) {
                const EVP_PKEY_ASN1_METHOD *ameth;
                ameth = EVP_PKEY_get0_asn1(sigkey);
                if (ameth)
                    EVP_PKEY_asn1_get0_info(NULL, NULL,
                                            NULL, NULL, &sig_name, ameth);
            }
            if (md)
                md_name = EVP_MD_name(md);
        }
        ret = 0;
        for (i = 0; i < argc; i++) {
            int r;
            if (BIO_read_filename(in, argv[i]) <= 0) {
                perror(argv[i]);
                ret++;
                continue;
            } else
                r = do_fp(out, buf, inp, separator, out_bin, sigkey, sigbuf,
                          siglen, sig_name, md_name, argv[i], bmd);
            if (r)
                ret = r;
            (void)BIO_reset(bmd);
        }
    }
 end:
    if (buf != NULL) {
        OPENSSL_cleanse(buf, BUFSIZE);
        OPENSSL_free(buf);
    }
    BIO_free(in);
    if (passin)
        OPENSSL_free(passin);
    BIO_free_all(out);
    EVP_PKEY_free(sigkey);
    if (sigopts)
        sk_OPENSSL_STRING_free(sigopts);
    if (macopts)
        sk_OPENSSL_STRING_free(macopts);
    if (sigbuf)
        OPENSSL_free(sigbuf);
    BIO_free(bmd);
    return (ret);
}
Example #25
0
static int
do_ca_cert_bootstrap(struct stream *stream)
{
    struct ssl_stream *sslv = ssl_stream_cast(stream);
    STACK_OF(X509) *chain;
    X509 *cert;
    FILE *file;
    int error;
    int fd;

    chain = SSL_get_peer_cert_chain(sslv->ssl);
    if (!chain || !sk_X509_num(chain)) {
        VLOG_ERR("could not bootstrap CA cert: no certificate presented by "
                 "peer");
        return EPROTO;
    }
    cert = sk_X509_value(chain, sk_X509_num(chain) - 1);

    /* Check that 'cert' is self-signed.  Otherwise it is not a CA
     * certificate and we should not attempt to use it as one. */
    error = X509_check_issued(cert, cert);
    if (error) {
        VLOG_ERR("could not bootstrap CA cert: obtained certificate is "
                 "not self-signed (%s)",
                 X509_verify_cert_error_string(error));
        if (sk_X509_num(chain) < 2) {
            VLOG_ERR("only one certificate was received, so probably the peer "
                     "is not configured to send its CA certificate");
        }
        return EPROTO;
    }

    fd = open(ca_cert.file_name, O_CREAT | O_EXCL | O_WRONLY, 0444);
    if (fd < 0) {
        if (errno == EEXIST) {
            VLOG_INFO_RL(&rl, "reading CA cert %s created by another process",
                         ca_cert.file_name);
            stream_ssl_set_ca_cert_file__(ca_cert.file_name, true, true);
            return EPROTO;
        } else {
            VLOG_ERR("could not bootstrap CA cert: creating %s failed: %s",
                     ca_cert.file_name, ovs_strerror(errno));
            return errno;
        }
    }

    file = fdopen(fd, "w");
    if (!file) {
        error = errno;
        VLOG_ERR("could not bootstrap CA cert: fdopen failed: %s",
                 ovs_strerror(error));
        unlink(ca_cert.file_name);
        return error;
    }

    if (!PEM_write_X509(file, cert)) {
        VLOG_ERR("could not bootstrap CA cert: PEM_write_X509 to %s failed: "
                 "%s", ca_cert.file_name,
                 ERR_error_string(ERR_get_error(), NULL));
        fclose(file);
        unlink(ca_cert.file_name);
        return EIO;
    }

    if (fclose(file)) {
        error = errno;
        VLOG_ERR("could not bootstrap CA cert: writing %s failed: %s",
                 ca_cert.file_name, ovs_strerror(error));
        unlink(ca_cert.file_name);
        return error;
    }

    VLOG_INFO("successfully bootstrapped CA cert to %s", ca_cert.file_name);
    log_ca_cert(ca_cert.file_name, cert);
    bootstrap_ca_cert = false;
    ca_cert.read = true;

    /* SSL_CTX_add_client_CA makes a copy of cert's relevant data. */
    SSL_CTX_add_client_CA(ctx, cert);

    SSL_CTX_set_cert_store(ctx, X509_STORE_new());
    if (SSL_CTX_load_verify_locations(ctx, ca_cert.file_name, NULL) != 1) {
        VLOG_ERR("SSL_CTX_load_verify_locations: %s",
                 ERR_error_string(ERR_get_error(), NULL));
        return EPROTO;
    }
    VLOG_INFO("killing successful connection to retry using CA cert");
    return EPROTO;
}
Example #26
0
File: t_req.c Project: 274914765/C
int X509_REQ_print_ex (BIO * bp, X509_REQ * x, unsigned long nmflags, unsigned long cflag)
{
    unsigned long l;

    int i;

    const char *neg;

    X509_REQ_INFO *ri;

    EVP_PKEY *pkey;

    STACK_OF (X509_ATTRIBUTE) * sk;
    STACK_OF (X509_EXTENSION) * exts;
    char mlch = ' ';

    int nmindent = 0;

    if ((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE)
    {
        mlch = '\n';
        nmindent = 12;
    }

    if (nmflags == X509_FLAG_COMPAT)
        nmindent = 16;


    ri = x->req_info;
    if (!(cflag & X509_FLAG_NO_HEADER))
    {
        if (BIO_write (bp, "Certificate Request:\n", 21) <= 0)
            goto err;
        if (BIO_write (bp, "    Data:\n", 10) <= 0)
            goto err;
    }
    if (!(cflag & X509_FLAG_NO_VERSION))
    {
        neg = (ri->version->type == V_ASN1_NEG_INTEGER) ? "-" : "";
        l = 0;
        for (i = 0; i < ri->version->length; i++)
        {
            l <<= 8;
            l += ri->version->data[i];
        }
        if (BIO_printf (bp, "%8sVersion: %s%lu (%s0x%lx)\n", "", neg, l, neg, l) <= 0)
            goto err;
    }
    if (!(cflag & X509_FLAG_NO_SUBJECT))
    {
        if (BIO_printf (bp, "        Subject:%c", mlch) <= 0)
            goto err;
        if (X509_NAME_print_ex (bp, ri->subject, nmindent, nmflags) < 0)
            goto err;
        if (BIO_write (bp, "\n", 1) <= 0)
            goto err;
    }
    if (!(cflag & X509_FLAG_NO_PUBKEY))
    {
        if (BIO_write (bp, "        Subject Public Key Info:\n", 33) <= 0)
            goto err;
        if (BIO_printf (bp, "%12sPublic Key Algorithm: ", "") <= 0)
            goto err;
        if (i2a_ASN1_OBJECT (bp, ri->pubkey->algor->algorithm) <= 0)
            goto err;
        if (BIO_puts (bp, "\n") <= 0)
            goto err;

        pkey = X509_REQ_get_pubkey (x);
        if (pkey == NULL)
        {
            BIO_printf (bp, "%12sUnable to load Public Key\n", "");
            ERR_print_errors (bp);
        }
        else
        {
            EVP_PKEY_print_public (bp, pkey, 16, NULL);
            EVP_PKEY_free (pkey);
        }
    }

    if (!(cflag & X509_FLAG_NO_ATTRIBUTES))
    {
        /* may not be */
        if (BIO_printf (bp, "%8sAttributes:\n", "") <= 0)
            goto err;

        sk = x->req_info->attributes;
        if (sk_X509_ATTRIBUTE_num (sk) == 0)
        {
            if (BIO_printf (bp, "%12sa0:00\n", "") <= 0)
                goto err;
        }
        else
        {
            for (i = 0; i < sk_X509_ATTRIBUTE_num (sk); i++)
            {
                ASN1_TYPE *at;

                X509_ATTRIBUTE *a;

                ASN1_BIT_STRING *bs = NULL;

                ASN1_TYPE *t;

                int j, type = 0, count = 1, ii = 0;

                a = sk_X509_ATTRIBUTE_value (sk, i);
                if (X509_REQ_extension_nid (OBJ_obj2nid (a->object)))
                    continue;
                if (BIO_printf (bp, "%12s", "") <= 0)
                    goto err;
                if ((j = i2a_ASN1_OBJECT (bp, a->object)) > 0)
                {
                    if (a->single)
                    {
                        t = a->value.single;
                        type = t->type;
                        bs = t->value.bit_string;
                    }
                    else
                    {
                        ii = 0;
                        count = sk_ASN1_TYPE_num (a->value.set);
get_next:
                        at = sk_ASN1_TYPE_value (a->value.set, ii);
                        type = at->type;
                        bs = at->value.asn1_string;
                    }
                }
                for (j = 25 - j; j > 0; j--)
                    if (BIO_write (bp, " ", 1) != 1)
                        goto err;
                if (BIO_puts (bp, ":") <= 0)
                    goto err;
                if ((type == V_ASN1_PRINTABLESTRING) || (type == V_ASN1_T61STRING) || (type == V_ASN1_IA5STRING))
                {
                    if (BIO_write (bp, (char *) bs->data, bs->length) != bs->length)
                        goto err;
                    BIO_puts (bp, "\n");
                }
                else
                {
                    BIO_puts (bp, "unable to print attribute\n");
                }
                if (++ii < count)
                    goto get_next;
            }
        }
    }
    if (!(cflag & X509_FLAG_NO_EXTENSIONS))
    {
        exts = X509_REQ_get_extensions (x);
        if (exts)
        {
            BIO_printf (bp, "%8sRequested Extensions:\n", "");
            for (i = 0; i < sk_X509_EXTENSION_num (exts); i++)
            {
                ASN1_OBJECT *obj;

                X509_EXTENSION *ex;

                int j;

                ex = sk_X509_EXTENSION_value (exts, i);
                if (BIO_printf (bp, "%12s", "") <= 0)
                    goto err;
                obj = X509_EXTENSION_get_object (ex);
                i2a_ASN1_OBJECT (bp, obj);
                j = X509_EXTENSION_get_critical (ex);
                if (BIO_printf (bp, ": %s\n", j ? "critical" : "") <= 0)
                    goto err;
                if (!X509V3_EXT_print (bp, ex, cflag, 16))
                {
                    BIO_printf (bp, "%16s", "");
                    M_ASN1_OCTET_STRING_print (bp, ex->value);
                }
                if (BIO_write (bp, "\n", 1) <= 0)
                    goto err;
            }
            sk_X509_EXTENSION_pop_free (exts, X509_EXTENSION_free);
        }
    }

    if (!(cflag & X509_FLAG_NO_SIGDUMP))
    {
        if (!X509_signature_print (bp, x->sig_alg, x->signature))
            goto err;
    }

    return (1);
err:
    X509err (X509_F_X509_REQ_PRINT_EX, ERR_R_BUF_LIB);
    return (0);
}
Example #27
0
/* loads in the certificate from the server */
int ssl2_set_certificate(SSL *s, int type, int len, const unsigned char *data)
	{
	STACK_OF(X509) *sk=NULL;
	EVP_PKEY *pkey=NULL;
	SESS_CERT *sc=NULL;
	int i;
	X509 *x509=NULL;
	int ret=0;
	
	x509=d2i_X509(NULL,&data,(long)len);
	if (x509 == NULL)
		{
		SSLerr(SSL_F_SSL2_SET_CERTIFICATE,ERR_R_X509_LIB);
		goto err;
		}

	if ((sk=sk_X509_new_null()) == NULL || !sk_X509_push(sk,x509))
		{
		SSLerr(SSL_F_SSL2_SET_CERTIFICATE,ERR_R_MALLOC_FAILURE);
		goto err;
		}

	i=ssl_verify_cert_chain(s,sk);
		
	if ((s->verify_mode != SSL_VERIFY_NONE) && (i <= 0))
		{
		SSLerr(SSL_F_SSL2_SET_CERTIFICATE,SSL_R_CERTIFICATE_VERIFY_FAILED);
		goto err;
		}
	ERR_clear_error(); /* but we keep s->verify_result */
	s->session->verify_result = s->verify_result;

	/* server's cert for this session */
	sc=ssl_sess_cert_new();
	if (sc == NULL)
		{
		ret= -1;
		goto err;
		}
	if (s->session->sess_cert) ssl_sess_cert_free(s->session->sess_cert);
	s->session->sess_cert=sc;

	sc->peer_pkeys[SSL_PKEY_RSA_ENC].x509=x509;
	sc->peer_key= &(sc->peer_pkeys[SSL_PKEY_RSA_ENC]);

	pkey=X509_get_pubkey(x509);
	x509=NULL;
	if (pkey == NULL)
		{
		SSLerr(SSL_F_SSL2_SET_CERTIFICATE,SSL_R_UNABLE_TO_EXTRACT_PUBLIC_KEY);
		goto err;
		}
	if (pkey->type != EVP_PKEY_RSA)
		{
		SSLerr(SSL_F_SSL2_SET_CERTIFICATE,SSL_R_PUBLIC_KEY_NOT_RSA);
		goto err;
		}

	if (!ssl_set_peer_cert_type(sc,SSL2_CT_X509_CERTIFICATE))
		goto err;
	ret=1;
err:
	sk_X509_free(sk);
	X509_free(x509);
	EVP_PKEY_free(pkey);
	return(ret);
	}
static ASN1_INTEGER *def_serial_cb(struct TS_resp_ctx *, void *);
static int def_time_cb(struct TS_resp_ctx *, void *, long *sec, long *usec);
static int def_extension_cb(struct TS_resp_ctx *, X509_EXTENSION *, void *);

static void TS_RESP_CTX_init(TS_RESP_CTX *ctx);
static void TS_RESP_CTX_cleanup(TS_RESP_CTX *ctx);
static int TS_RESP_check_request(TS_RESP_CTX *ctx);
static ASN1_OBJECT *TS_RESP_get_policy(TS_RESP_CTX *ctx);
static TS_TST_INFO *TS_RESP_create_tst_info(TS_RESP_CTX *ctx, 
					    ASN1_OBJECT *policy);
static int TS_RESP_process_extensions(TS_RESP_CTX *ctx);
static int TS_RESP_sign(TS_RESP_CTX *ctx);

static ESS_SIGNING_CERT *ESS_SIGNING_CERT_new_init(X509 *signcert, 
						   STACK_OF(X509) *certs);
static ESS_CERT_ID *ESS_CERT_ID_new_init(X509 *cert, int issuer_needed);
static int TS_TST_INFO_content_new(PKCS7 *p7);
static int ESS_add_signing_cert(PKCS7_SIGNER_INFO *si, ESS_SIGNING_CERT *sc);

static ASN1_GENERALIZEDTIME *TS_RESP_set_genTime_with_precision(
	ASN1_GENERALIZEDTIME *, long, long, unsigned);

/* Default callbacks for response generation. */

static ASN1_INTEGER *def_serial_cb(struct TS_resp_ctx *ctx, void *data)
	{
	ASN1_INTEGER *serial = ASN1_INTEGER_new();
	if (!serial) goto err;
	if (!ASN1_INTEGER_set(serial, 1)) goto err;
	return serial;
Example #29
0
 *
 */

#include <openssl/bio.h>
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/pem.h>
#include <openssl/pkcs7.h>
#include <openssl/x509.h>
#include <openssl/err.h>
#ifdef OPENSSL_SYS_WINDOWS
#include <stdio.h>
#include <stdlib.h>
#endif

int PKCS7_add_attrib_smimecap(PKCS7_SIGNER_INFO *si, STACK_OF(X509_ALGOR) *cap)
{
	ASN1_STRING *seq;
	if(!(seq = ASN1_STRING_new())) {
		PKCS7err(PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP,ERR_R_MALLOC_FAILURE);
		return 0;
	}
	seq->length = ASN1_item_i2d((ASN1_VALUE *)cap,&seq->data,
				ASN1_ITEM_rptr(X509_ALGORS));
        return PKCS7_add_signed_attribute(si, NID_SMIMECapabilities,
							V_ASN1_SEQUENCE, seq);
}

STACK_OF(X509_ALGOR) *PKCS7_get_smimecap(PKCS7_SIGNER_INFO *si)
	{
	ASN1_TYPE *cap;
Example #30
0
#  else
#   include <novsock2.h>
#  endif
# endif

/* Maximum leeway in validity period: default 5 minutes */
# define MAX_VALIDITY_PERIOD    (5 * 60)

static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert,
                         const EVP_MD *cert_id_md, X509 *issuer,
                         STACK_OF(OCSP_CERTID) *ids);
static int add_ocsp_serial(OCSP_REQUEST **req, char *serial,
                           const EVP_MD *cert_id_md, X509 *issuer,
                           STACK_OF(OCSP_CERTID) *ids);
static void print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req,
                              STACK_OF(OPENSSL_STRING) *names,
                              STACK_OF(OCSP_CERTID) *ids, long nsec,
                              long maxage);
static void make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req,
                              CA_DB *db, X509 *ca, X509 *rcert,
                              EVP_PKEY *rkey, const EVP_MD *md,
                              STACK_OF(X509) *rother, unsigned long flags,
                              int nmin, int ndays, int badsig);

static char **lookup_serial(CA_DB *db, ASN1_INTEGER *ser);
static BIO *init_responder(const char *port);
static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio);
static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp);
static OCSP_RESPONSE *query_responder(BIO *cbio, const char *host,
                                      const char *path,
                                      const STACK_OF(CONF_VALUE) *headers,