Example #1
0
static int
ssl_set_cert(CERT *c, X509 *x)
{
	EVP_PKEY *pkey;
	int i;

	pkey = X509_get_pubkey(x);
	if (pkey == NULL) {
		SSLerrorx(SSL_R_X509_LIB);
		return (0);
	}

	i = ssl_cert_type(x, pkey);
	if (i < 0) {
		SSLerrorx(SSL_R_UNKNOWN_CERTIFICATE_TYPE);
		EVP_PKEY_free(pkey);
		return (0);
	}

	if (c->pkeys[i].privatekey != NULL) {
		EVP_PKEY_copy_parameters(pkey, c->pkeys[i].privatekey);
		ERR_clear_error();

		/*
		 * Don't check the public/private key, this is mostly
		 * for smart cards.
		 */
		if ((c->pkeys[i].privatekey->type == EVP_PKEY_RSA) &&
			(RSA_flags(c->pkeys[i].privatekey->pkey.rsa) &
		RSA_METHOD_FLAG_NO_CHECK))
;
		else
		if (!X509_check_private_key(x, c->pkeys[i].privatekey)) {
			/*
			 * don't fail for a cert/key mismatch, just free
			 * current private key (when switching to a different
			 * cert & key, first this function should be used,
			 * then ssl_set_pkey
			 */
			EVP_PKEY_free(c->pkeys[i].privatekey);
			c->pkeys[i].privatekey = NULL;
			/* clear error queue */
			ERR_clear_error();
		}
	}

	EVP_PKEY_free(pkey);

	X509_free(c->pkeys[i].x509);
	CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
	c->pkeys[i].x509 = x;
	c->key = &(c->pkeys[i]);

	c->valid = 0;
	return (1);
}
Example #2
0
int
SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x)
{
	if (x == NULL) {
		SSLerrorx(ERR_R_PASSED_NULL_PARAMETER);
		return (0);
	}
	return (ssl_set_cert(ctx->internal->cert, x));
}
Example #3
0
int
SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey)
{
	if (pkey == NULL) {
		SSLerrorx(ERR_R_PASSED_NULL_PARAMETER);
		return (0);
	}
	return (ssl_set_pkey(ctx->internal->cert, pkey));
}
Example #4
0
int
SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type)
{
	int j;
	BIO *in;
	int ret = 0;
	X509 *x = NULL;

	in = BIO_new(BIO_s_file_internal());
	if (in == NULL) {
		SSLerrorx(ERR_R_BUF_LIB);
		goto end;
	}

	if (BIO_read_filename(in, file) <= 0) {
		SSLerrorx(ERR_R_SYS_LIB);
		goto end;
	}
	if (type == SSL_FILETYPE_ASN1) {
		j = ERR_R_ASN1_LIB;
		x = d2i_X509_bio(in, NULL);
	} else if (type == SSL_FILETYPE_PEM) {
		j = ERR_R_PEM_LIB;
		x = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback,
		    ctx->default_passwd_callback_userdata);
	} else {
		SSLerrorx(SSL_R_BAD_SSL_FILETYPE);
		goto end;
	}

	if (x == NULL) {
		SSLerrorx(j);
		goto end;
	}

	ret = SSL_CTX_use_certificate(ctx, x);
end:
	X509_free(x);
	BIO_free(in);
	return (ret);
}
Example #5
0
int
SSL_SESSION_set1_id(SSL_SESSION *s, const unsigned char *sid,
    unsigned int sid_len)
{
	if (sid_len > SSL_MAX_SSL_SESSION_ID_LENGTH) {
		SSLerrorx(SSL_R_SSL_SESSION_ID_TOO_LONG);
		return 0;
	}
	s->session_id_length = sid_len;
	memmove(s->session_id, sid, sid_len);
	return 1;
}
Example #6
0
int
SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type)
{
	int j, ret = 0;
	BIO *in;
	EVP_PKEY *pkey = NULL;

	in = BIO_new(BIO_s_file_internal());
	if (in == NULL) {
		SSLerrorx(ERR_R_BUF_LIB);
		goto end;
	}

	if (BIO_read_filename(in, file) <= 0) {
		SSLerrorx(ERR_R_SYS_LIB);
		goto end;
	}
	if (type == SSL_FILETYPE_PEM) {
		j = ERR_R_PEM_LIB;
		pkey = PEM_read_bio_PrivateKey(in, NULL,
		    ctx->default_passwd_callback,
		    ctx->default_passwd_callback_userdata);
	} else if (type == SSL_FILETYPE_ASN1) {
		j = ERR_R_ASN1_LIB;
		pkey = d2i_PrivateKey_bio(in, NULL);
	} else {
		SSLerrorx(SSL_R_BAD_SSL_FILETYPE);
		goto end;
	}
	if (pkey == NULL) {
		SSLerrorx(j);
		goto end;
	}
	ret = SSL_CTX_use_PrivateKey(ctx, pkey);
	EVP_PKEY_free(pkey);
end:
	BIO_free(in);
	return (ret);
}
Example #7
0
int
SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa)
{
	int ret;
	EVP_PKEY *pkey;

	if (rsa == NULL) {
		SSLerrorx(ERR_R_PASSED_NULL_PARAMETER);
		return (0);
	}
	if ((pkey = EVP_PKEY_new()) == NULL) {
		SSLerrorx(ERR_R_EVP_LIB);
		return (0);
	}

	RSA_up_ref(rsa);
	EVP_PKEY_assign_RSA(pkey, rsa);

	ret = ssl_set_pkey(ctx->internal->cert, pkey);
	EVP_PKEY_free(pkey);
	return (ret);
}
Example #8
0
int
SSL_SESSION_set1_id_context(SSL_SESSION *s, const unsigned char *sid_ctx,
    unsigned int sid_ctx_len)
{
	if (sid_ctx_len > SSL_MAX_SID_CTX_LENGTH) {
		SSLerrorx(SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG);
		return 0;
	}
	s->sid_ctx_length = sid_ctx_len;
	memcpy(s->sid_ctx, sid_ctx, sid_ctx_len);

	return 1;
}
Example #9
0
int
SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file)
{
	BIO *in;
	int ret = 0;

	in = BIO_new(BIO_s_file_internal());
	if (in == NULL) {
		SSLerrorx(ERR_R_BUF_LIB);
		goto end;
	}

	if (BIO_read_filename(in, file) <= 0) {
		SSLerrorx(ERR_R_SYS_LIB);
		goto end;
	}

	ret = ssl_ctx_use_certificate_chain_bio(ctx, in);

end:
	BIO_free(in);
	return (ret);
}
Example #10
0
CERT *
ssl_cert_new(void)
{
	CERT *ret;

	ret = calloc(1, sizeof(CERT));
	if (ret == NULL) {
		SSLerrorx(ERR_R_MALLOC_FAILURE);
		return (NULL);
	}
	ret->key = &(ret->pkeys[SSL_PKEY_RSA_ENC]);
	ret->references = 1;
	return (ret);
}
Example #11
0
SSL_SESSION *
SSL_SESSION_new(void)
{
	SSL_SESSION *ss;

	if (!OPENSSL_init_ssl(0, NULL)) {
		SSLerrorx(SSL_R_LIBRARY_BUG);
		return(NULL);
	}

	if ((ss = calloc(1, sizeof(*ss))) == NULL) {
		SSLerrorx(ERR_R_MALLOC_FAILURE);
		return (NULL);
	}
	if ((ss->internal = calloc(1, sizeof(*ss->internal))) == NULL) {
		free(ss);
		SSLerrorx(ERR_R_MALLOC_FAILURE);
		return (NULL);
	}

	ss->verify_result = 1; /* avoid 0 (= X509_V_OK) just in case */
	ss->references = 1;
	ss->timeout=60*5+4; /* 5 minute timeout by default */
	ss->time = time(NULL);
	ss->internal->prev = NULL;
	ss->internal->next = NULL;
	ss->tlsext_hostname = NULL;

	ss->internal->tlsext_ecpointformatlist_length = 0;
	ss->internal->tlsext_ecpointformatlist = NULL;
	ss->internal->tlsext_supportedgroups_length = 0;
	ss->internal->tlsext_supportedgroups = NULL;

	CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ss, &ss->internal->ex_data);

	return (ss);
}
Example #12
0
int
SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, long len)
{
	int ret;
	RSA *rsa;

	if ((rsa = d2i_RSAPrivateKey(NULL, &d, (long)len)) == NULL) {
		SSLerrorx(ERR_R_ASN1_LIB);
		return (0);
	}

	ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa);
	RSA_free(rsa);
	return (ret);
}
Example #13
0
int
SSL_SESSION_print_fp(FILE *fp, const SSL_SESSION *x)
{
	BIO *b;
	int ret;

	if ((b = BIO_new(BIO_s_file_internal())) == NULL) {
		SSLerrorx(ERR_R_BUF_LIB);
		return (0);
	}
	BIO_set_fp(b, fp, BIO_NOCLOSE);
	ret = SSL_SESSION_print(b, x);
	BIO_free(b);
	return (ret);
}
Example #14
0
int
SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d)
{
	X509 *x;
	int ret;

	x = d2i_X509(NULL, &d, (long)len);
	if (x == NULL) {
		SSLerrorx(ERR_R_ASN1_LIB);
		return (0);
	}

	ret = SSL_CTX_use_certificate(ctx, x);
	X509_free(x);
	return (ret);
}
Example #15
0
int
SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, const unsigned char *d,
    long len)
{
	int ret;
	EVP_PKEY *pkey;

	if ((pkey = d2i_PrivateKey(type, NULL, &d, (long)len)) == NULL) {
		SSLerrorx(ERR_R_ASN1_LIB);
		return (0);
	}

	ret = SSL_CTX_use_PrivateKey(ctx, pkey);
	EVP_PKEY_free(pkey);
	return (ret);
}
Example #16
0
int
SSL_CTX_use_certificate_chain_mem(SSL_CTX *ctx, void *buf, int len)
{
	BIO *in;
	int ret = 0;

	in = BIO_new_mem_buf(buf, len);
	if (in == NULL) {
		SSLerrorx(ERR_R_BUF_LIB);
		goto end;
	}

	ret = ssl_ctx_use_certificate_chain_bio(ctx, in);

end:
	BIO_free(in);
	return (ret);
}
Example #17
0
/*
 * Read a bio that contains our certificate in "PEM" format,
 * possibly followed by a sequence of CA certificates that should be
 * sent to the peer in the Certificate message.
 */
static int
ssl_ctx_use_certificate_chain_bio(SSL_CTX *ctx, BIO *in)
{
	X509 *ca, *x = NULL;
	unsigned long err;
	int ret = 0;

	if ((x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback,
	    ctx->default_passwd_callback_userdata)) == NULL) {
		SSLerrorx(ERR_R_PEM_LIB);
		goto err;
	}

	if (!SSL_CTX_use_certificate(ctx, x))
		goto err;

	if (!ssl_cert_set0_chain(ctx->internal->cert, NULL))
		goto err;

	/* Process any additional CA certificates. */
	while ((ca = PEM_read_bio_X509(in, NULL,
	    ctx->default_passwd_callback,
	    ctx->default_passwd_callback_userdata)) != NULL) {
		if (!ssl_cert_add0_chain_cert(ctx->internal->cert, ca)) {
			X509_free(ca);
			goto err;
		}
	}

	/* When the while loop ends, it's usually just EOF. */
	err = ERR_peek_last_error();
	if (ERR_GET_LIB(err) == ERR_LIB_PEM &&
	    ERR_GET_REASON(err) == PEM_R_NO_START_LINE) {
		ERR_clear_error();
		ret = 1;
	}

 err:
	X509_free(x);

	return (ret);
}
Example #18
0
static int
ssl_set_pkey(CERT *c, EVP_PKEY *pkey)
{
	int i;

	i = ssl_cert_type(NULL, pkey);
	if (i < 0) {
		SSLerrorx(SSL_R_UNKNOWN_CERTIFICATE_TYPE);
		return (0);
	}

	if (c->pkeys[i].x509 != NULL) {
		EVP_PKEY *pktmp;
		pktmp = X509_get_pubkey(c->pkeys[i].x509);
		EVP_PKEY_copy_parameters(pktmp, pkey);
		EVP_PKEY_free(pktmp);
		ERR_clear_error();

		/*
		 * Don't check the public/private key, this is mostly
		 * for smart cards.
		 */
		if ((pkey->type == EVP_PKEY_RSA) &&
			(RSA_flags(pkey->pkey.rsa) & RSA_METHOD_FLAG_NO_CHECK))
;
		else
		if (!X509_check_private_key(c->pkeys[i].x509, pkey)) {
			X509_free(c->pkeys[i].x509);
			c->pkeys[i].x509 = NULL;
			return 0;
		}
	}

	EVP_PKEY_free(c->pkeys[i].privatekey);
	CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
	c->pkeys[i].privatekey = pkey;
	c->key = &(c->pkeys[i]);

	c->valid = 0;
	return (1);
}
Example #19
0
SSL_SESSION *
d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, long length)
{
	CBS cbs, session, cipher_suite, session_id, master_key, peer_cert;
	CBS hostname, ticket;
	uint64_t version, tls_version, stime, timeout, verify_result, lifetime;
	const unsigned char *peer_cert_bytes;
	uint16_t cipher_value;
	SSL_SESSION *s = NULL;
	size_t data_len;
	int present;

	if (a != NULL)
		s = *a;

	if (s == NULL) {
		if ((s = SSL_SESSION_new()) == NULL) {
			SSLerrorx(ERR_R_MALLOC_FAILURE);
			return (NULL);
		}
	}

	CBS_init(&cbs, *pp, length);

	if (!CBS_get_asn1(&cbs, &session, CBS_ASN1_SEQUENCE))
		goto err;

	/* Session ASN1 version. */
	if (!CBS_get_asn1_uint64(&session, &version))
		goto err;
	if (version != SSL_SESSION_ASN1_VERSION)
		goto err;

	/* TLS/SSL Protocol Version. */
	if (!CBS_get_asn1_uint64(&session, &tls_version))
		goto err;
	if (tls_version > INT_MAX)
		goto err;
	s->ssl_version = (int)tls_version;

	/* Cipher suite. */
	if (!CBS_get_asn1(&session, &cipher_suite, CBS_ASN1_OCTETSTRING))
		goto err;
	if (!CBS_get_u16(&cipher_suite, &cipher_value))
		goto err;
	if (CBS_len(&cipher_suite) != 0)
		goto err;

	/* XXX - populate cipher instead? */
	s->cipher = NULL;
	s->cipher_id = SSL3_CK_ID | cipher_value;

	/* Session ID. */
	if (!CBS_get_asn1(&session, &session_id, CBS_ASN1_OCTETSTRING))
		goto err;
	if (!CBS_write_bytes(&session_id, s->session_id, sizeof(s->session_id),
	    &data_len))
		goto err;
	if (data_len > UINT_MAX)
		goto err;
	s->session_id_length = (unsigned int)data_len;

	/* Master key. */
	if (!CBS_get_asn1(&session, &master_key, CBS_ASN1_OCTETSTRING))
		goto err;
	if (!CBS_write_bytes(&master_key, s->master_key, sizeof(s->master_key),
	    &data_len))
		goto err;
	if (data_len > INT_MAX)
		goto err;
	s->master_key_length = (int)data_len;

	/* Time [1]. */
	s->time = time(NULL);
	if (!CBS_get_optional_asn1_uint64(&session, &stime, SSLASN1_TIME_TAG,
	    0))
		goto err;
	if (stime > time_max())
		goto err;
	if (stime != 0)
		s->time = (time_t)stime;

	/* Timeout [2]. */
	s->timeout = 3;
	if (!CBS_get_optional_asn1_uint64(&session, &timeout,
	    SSLASN1_TIMEOUT_TAG, 0))
		goto err;
	if (timeout > LONG_MAX)
		goto err;
	if (timeout != 0)
		s->timeout = (long)timeout;
	
	/* Peer certificate [3]. */
	X509_free(s->peer);
	s->peer = NULL;
	if (!CBS_get_optional_asn1(&session, &peer_cert, &present,
	    SSLASN1_PEER_CERT_TAG))
		goto err;
	if (present) {
		data_len = CBS_len(&peer_cert);
		if (data_len > LONG_MAX)
			goto err;
		peer_cert_bytes = CBS_data(&peer_cert);
		if (d2i_X509(&s->peer, &peer_cert_bytes,
		    (long)data_len) == NULL)
			goto err;
	}

	/* Session ID context [4]. */
	s->sid_ctx_length = 0;
	if (!CBS_get_optional_asn1_octet_string(&session, &session_id, &present,
	    SSLASN1_SESSION_ID_CTX_TAG))
		goto err;
	if (present) {
		if (!CBS_write_bytes(&session_id, (uint8_t *)&s->sid_ctx,
		    sizeof(s->sid_ctx), &data_len))
			goto err;
		if (data_len > UINT_MAX)
			goto err;
		s->sid_ctx_length = (unsigned int)data_len;
	}

	/* Verify result [5]. */
	s->verify_result = X509_V_OK;
	if (!CBS_get_optional_asn1_uint64(&session, &verify_result,
	    SSLASN1_VERIFY_RESULT_TAG, X509_V_OK))
		goto err;
	if (verify_result > LONG_MAX)
		goto err;
	s->verify_result = (long)verify_result;

	/* Hostname [6]. */
	free(s->tlsext_hostname);
	s->tlsext_hostname = NULL;
	if (!CBS_get_optional_asn1_octet_string(&session, &hostname, &present,
	    SSLASN1_HOSTNAME_TAG))
		goto err;
	if (present) {
		if (CBS_contains_zero_byte(&hostname))
			goto err;
		if (!CBS_strdup(&hostname, &s->tlsext_hostname))
			goto err;
	}
	
	/* PSK identity hint [7]. */
	/* PSK identity [8]. */

	/* Ticket lifetime [9]. */
	s->tlsext_tick_lifetime_hint = 0;
	/* XXX - tlsext_ticklen is not yet set... */
	if (s->tlsext_ticklen > 0 && s->session_id_length > 0)
		s->tlsext_tick_lifetime_hint = -1;
	if (!CBS_get_optional_asn1_uint64(&session, &lifetime,
	    SSLASN1_LIFETIME_TAG, 0))
		goto err;
	if (lifetime > LONG_MAX)
		goto err;
	if (lifetime > 0)
		s->tlsext_tick_lifetime_hint = (long)lifetime;

	/* Ticket [10]. */
	free(s->tlsext_tick);
	s->tlsext_tick = NULL;
	if (!CBS_get_optional_asn1_octet_string(&session, &ticket, &present,
	    SSLASN1_TICKET_TAG))
		goto err;
	if (present) {
		if (!CBS_stow(&ticket, &s->tlsext_tick, &s->tlsext_ticklen))
			goto err;
	}

	/* Compression method [11]. */
	/* SRP username [12]. */

	*pp = CBS_data(&cbs);

	if (a != NULL)
		*a = s;

	return (s);

err:
	ERR_asprintf_error_data("offset=%d", (int)(CBS_data(&cbs) - *pp));

	if (s != NULL && (a == NULL || *a != s))
		SSL_SESSION_free(s);

	return (NULL);
}
Example #20
0
CERT *
ssl_cert_dup(CERT *cert)
{
	CERT *ret;
	int i;

	ret = calloc(1, sizeof(CERT));
	if (ret == NULL) {
		SSLerrorx(ERR_R_MALLOC_FAILURE);
		return (NULL);
	}

	/*
	 * same as ret->key = ret->pkeys + (cert->key - cert->pkeys),
	 * if you find that more readable
	 */
	ret->key = &ret->pkeys[cert->key - &cert->pkeys[0]];

	ret->valid = cert->valid;
	ret->mask_k = cert->mask_k;
	ret->mask_a = cert->mask_a;

	if (cert->dh_tmp != NULL) {
		ret->dh_tmp = DHparams_dup(cert->dh_tmp);
		if (ret->dh_tmp == NULL) {
			SSLerrorx(ERR_R_DH_LIB);
			goto err;
		}
		if (cert->dh_tmp->priv_key) {
			BIGNUM *b = BN_dup(cert->dh_tmp->priv_key);
			if (!b) {
				SSLerrorx(ERR_R_BN_LIB);
				goto err;
			}
			ret->dh_tmp->priv_key = b;
		}
		if (cert->dh_tmp->pub_key) {
			BIGNUM *b = BN_dup(cert->dh_tmp->pub_key);
			if (!b) {
				SSLerrorx(ERR_R_BN_LIB);
				goto err;
			}
			ret->dh_tmp->pub_key = b;
		}
	}
	ret->dh_tmp_cb = cert->dh_tmp_cb;
	ret->dh_tmp_auto = cert->dh_tmp_auto;

	for (i = 0; i < SSL_PKEY_NUM; i++) {
		if (cert->pkeys[i].x509 != NULL) {
			ret->pkeys[i].x509 = cert->pkeys[i].x509;
			CRYPTO_add(&ret->pkeys[i].x509->references, 1,
			CRYPTO_LOCK_X509);
		}

		if (cert->pkeys[i].privatekey != NULL) {
			ret->pkeys[i].privatekey = cert->pkeys[i].privatekey;
			CRYPTO_add(&ret->pkeys[i].privatekey->references, 1,
			CRYPTO_LOCK_EVP_PKEY);

			switch (i) {
				/*
				 * If there was anything special to do for
				 * certain types of keys, we'd do it here.
				 * (Nothing at the moment, I think.)
				 */

			case SSL_PKEY_RSA_ENC:
			case SSL_PKEY_RSA_SIGN:
				/* We have an RSA key. */
				break;

			case SSL_PKEY_DH_RSA:
				/* We have a DH key. */
				break;

			case SSL_PKEY_ECC:
				/* We have an ECC key */
				break;

			default:
				/* Can't happen. */
				SSLerrorx(SSL_R_LIBRARY_BUG);
			}
		}

		if (cert->pkeys[i].chain != NULL) {
			if ((ret->pkeys[i].chain =
			    X509_chain_up_ref(cert->pkeys[i].chain)) == NULL)
				goto err;
		}
	}

	/*
	 * ret->extra_certs *should* exist, but currently the own certificate
	 * chain is held inside SSL_CTX
	 */

	ret->references = 1;

	return (ret);

 err:
	DH_free(ret->dh_tmp);

	for (i = 0; i < SSL_PKEY_NUM; i++) {
		X509_free(ret->pkeys[i].x509);
		EVP_PKEY_free(ret->pkeys[i].privatekey);
		sk_X509_pop_free(ret->pkeys[i].chain, X509_free);
	}
	free (ret);
	return NULL;
}