# ifndef OPENSSL_NO_NEXTPROTONEG
s->next_proto_negotiated = NULL;
# endif
+
+ if (s->ctx->alpn_client_proto_list)
+ {
+ s->alpn_client_proto_list =
+ OPENSSL_malloc(s->ctx->alpn_client_proto_list_len);
+ if (s->alpn_client_proto_list == NULL)
+ goto err;
+ memcpy(s->alpn_client_proto_list, s->ctx->alpn_client_proto_list,
+ s->ctx->alpn_client_proto_list_len);
+ s->alpn_client_proto_list_len = s->ctx->alpn_client_proto_list_len;
+ }
#endif
s->verify_result=X509_V_OK;
return X509_VERIFY_PARAM_set1(ssl->param, vpm);
}
+X509_VERIFY_PARAM *SSL_CTX_get0_param(SSL_CTX *ctx)
+ {
+ return ctx->param;
+ }
+
+X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl)
+ {
+ return ssl->param;
+ }
+
void SSL_certs_clear(SSL *s)
{
ssl_cert_clear_certs(s->cert);
sk_OCSP_RESPID_pop_free(s->tlsext_ocsp_ids, OCSP_RESPID_free);
if (s->tlsext_ocsp_resp)
OPENSSL_free(s->tlsext_ocsp_resp);
+ if (s->alpn_client_proto_list)
+ OPENSSL_free(s->alpn_client_proto_list);
#endif
if (s->client_CA != NULL)
return 0;
#endif
- if (SSL_version(s) == DTLS1_VERSION ||
- SSL_version(s) == DTLS1_BAD_VER)
+ if (SSL_IS_DTLS(s))
{
s->d1->mtu = larg;
return larg;
{
switch (cmd)
{
+#ifndef OPENSSL_NO_EC
case SSL_CTRL_SET_CURVES_LIST:
return tls1_set_curves_list(NULL, NULL, parg);
+#endif
case SSL_CTRL_SET_SIGALGS_LIST:
case SSL_CTRL_SET_CLIENT_SIGALGS_LIST:
return tls1_set_sigalgs_list(NULL, parg, 0);
return(NULL);
}
+STACK_OF(SSL_CIPHER) *SSL_get1_supported_ciphers(SSL *s)
+ {
+ STACK_OF(SSL_CIPHER) *sk = NULL, *ciphers;
+ int i;
+ ciphers = SSL_get_ciphers(s);
+ if (!ciphers)
+ return NULL;
+ ssl_set_client_disabled(s);
+ for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++)
+ {
+ const SSL_CIPHER *c = sk_SSL_CIPHER_value(ciphers, i);
+ if (!ssl_cipher_disabled(s, c, SSL_SECOP_CIPHER_SUPPORTED))
+ {
+ if (!sk)
+ sk = sk_SSL_CIPHER_new_null();
+ if (!sk)
+ return NULL;
+ if (!sk_SSL_CIPHER_push(sk, c))
+ {
+ sk_SSL_CIPHER_free(sk);
+ return NULL;
+ }
+ }
+ }
+ return sk;
+ }
+
/** return a STACK of the ciphers available for the SSL and in order of
* algorithm id */
STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL *s)
p=buf;
sk=s->session->ciphers;
+
+ if (sk_SSL_CIPHER_num(sk) == 0)
+ return NULL;
+
for (i=0; i<sk_SSL_CIPHER_num(sk); i++)
{
int n;
{
int i,j=0;
SSL_CIPHER *c;
- CERT *ct = s->cert;
unsigned char *q;
int no_scsv = s->renegotiate;
/* Set disabled masks for this session */
{
c=sk_SSL_CIPHER_value(sk,i);
/* Skip disabled ciphers */
- if (c->algorithm_ssl & ct->mask_ssl ||
- c->algorithm_mkey & ct->mask_k ||
- c->algorithm_auth & ct->mask_a)
+ if (ssl_cipher_disabled(s, c, SSL_SECOP_CIPHER_SUPPORTED))
continue;
#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL
if (c->id == SSL3_CK_SCSV)
return -1;
}
-# ifndef OPENSSL_NO_NEXTPROTONEG
/* SSL_select_next_proto implements the standard protocol selection. It is
* expected that this function is called from the callback set by
* SSL_CTX_set_next_proto_select_cb.
return status;
}
+# ifndef OPENSSL_NO_NEXTPROTONEG
/* SSL_get0_next_proto_negotiated sets *data and *len to point to the client's
* requested protocol for this connection and returns 0. If the client didn't
* request any protocol, then *data is set to NULL.
ctx->next_proto_select_cb_arg = arg;
}
# endif
-#endif
+
+/* SSL_CTX_set_alpn_protos sets the ALPN protocol list on |ctx| to |protos|.
+ * |protos| must be in wire-format (i.e. a series of non-empty, 8-bit
+ * length-prefixed strings).
+ *
+ * Returns 0 on success. */
+int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char* protos,
+ unsigned protos_len)
+ {
+ if (ctx->alpn_client_proto_list)
+ OPENSSL_free(ctx->alpn_client_proto_list);
+
+ ctx->alpn_client_proto_list = OPENSSL_malloc(protos_len);
+ if (!ctx->alpn_client_proto_list)
+ return 1;
+ memcpy(ctx->alpn_client_proto_list, protos, protos_len);
+ ctx->alpn_client_proto_list_len = protos_len;
+
+ return 0;
+ }
+
+/* SSL_set_alpn_protos sets the ALPN protocol list on |ssl| to |protos|.
+ * |protos| must be in wire-format (i.e. a series of non-empty, 8-bit
+ * length-prefixed strings).
+ *
+ * Returns 0 on success. */
+int SSL_set_alpn_protos(SSL *ssl, const unsigned char* protos,
+ unsigned protos_len)
+ {
+ if (ssl->alpn_client_proto_list)
+ OPENSSL_free(ssl->alpn_client_proto_list);
+
+ ssl->alpn_client_proto_list = OPENSSL_malloc(protos_len);
+ if (!ssl->alpn_client_proto_list)
+ return 1;
+ memcpy(ssl->alpn_client_proto_list, protos, protos_len);
+ ssl->alpn_client_proto_list_len = protos_len;
+
+ return 0;
+ }
+
+/* SSL_CTX_set_alpn_select_cb sets a callback function on |ctx| that is called
+ * during ClientHello processing in order to select an ALPN protocol from the
+ * client's list of offered protocols. */
+void SSL_CTX_set_alpn_select_cb(SSL_CTX* ctx,
+ int (*cb) (SSL *ssl,
+ const unsigned char **out,
+ unsigned char *outlen,
+ const unsigned char *in,
+ unsigned int inlen,
+ void *arg),
+ void *arg)
+ {
+ ctx->alpn_select_cb = cb;
+ ctx->alpn_select_cb_arg = arg;
+ }
+
+/* SSL_get0_alpn_selected gets the selected ALPN protocol (if any) from |ssl|.
+ * On return it sets |*data| to point to |*len| bytes of protocol name (not
+ * including the leading length-prefix byte). If the server didn't respond with
+ * a negotiated protocol then |*len| will be zero. */
+void SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data,
+ unsigned *len)
+ {
+ *data = NULL;
+ if (ssl->s3)
+ *data = ssl->s3->alpn_selected;
+ if (*data == NULL)
+ *len = 0;
+ else
+ *len = ssl->s3->alpn_selected_len;
+ }
+
+#endif /* !OPENSSL_NO_TLSEXT */
int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen,
const char *label, size_t llen, const unsigned char *p, size_t plen,
CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_CTX, ret, &ret->ex_data);
ret->extra_certs=NULL;
- ret->comp_methods=SSL_COMP_get_compression_methods();
+ /* No compression for DTLS */
+ if (!(meth->ssl3_enc->enc_flags & SSL_ENC_FLAG_DTLS))
+ ret->comp_methods=SSL_COMP_get_compression_methods();
ret->max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH;
if (a->tlsext_ellipticcurvelist)
OPENSSL_free(a->tlsext_ellipticcurvelist);
# endif /* OPENSSL_NO_EC */
+ if (a->alpn_client_proto_list != NULL)
+ OPENSSL_free(a->alpn_client_proto_list);
#endif
OPENSSL_free(a);
int rsa_enc_export,dh_rsa_export,dh_dsa_export;
int rsa_tmp_export,dh_tmp_export,kl;
unsigned long mask_k,mask_a,emask_k,emask_a;
- int have_ecc_cert, ecdh_ok, ecdsa_ok, ecc_pkey_size;
+#ifndef OPENSSL_NO_ECDSA
+ int have_ecc_cert, ecdsa_ok, ecc_pkey_size;
+#endif
#ifndef OPENSSL_NO_ECDH
- int have_ecdh_tmp;
+ int have_ecdh_tmp, ecdh_ok;
#endif
+#ifndef OPENSSL_NO_EC
X509 *x = NULL;
EVP_PKEY *ecc_pkey = NULL;
int signature_nid = 0, pk_nid = 0, md_nid = 0;
-
+#endif
if (c == NULL) return;
kl=SSL_C_EXPORT_PKEYLENGTH(cipher);
rsa_tmp=rsa_tmp_export=0;
#endif
#ifndef OPENSSL_NO_DH
- dh_tmp=(c->dh_tmp != NULL || c->dh_tmp_cb != NULL);
- dh_tmp_export=(c->dh_tmp_cb != NULL ||
+ dh_tmp=(c->dh_tmp != NULL || c->dh_tmp_cb != NULL || c->dh_tmp_auto);
+ dh_tmp_export= !c->dh_tmp_auto && (c->dh_tmp_cb != NULL ||
(dh_tmp && DH_size(c->dh_tmp)*8 <= kl));
#else
dh_tmp=dh_tmp_export=0;
dh_dsa= cpk->valid_flags & CERT_PKEY_VALID;
dh_dsa_export=(dh_dsa && EVP_PKEY_size(cpk->privatekey)*8 <= kl);
cpk= &(c->pkeys[SSL_PKEY_ECC]);
+#ifndef OPENSSL_NO_EC
have_ecc_cert= cpk->valid_flags & CERT_PKEY_VALID;
+#endif
mask_k=0;
mask_a=0;
emask_k=0;
emask_k|=SSL_kRSA;
#if 0
- /* The match needs to be both kEDH and aRSA or aDSA, so don't worry */
+ /* The match needs to be both kDHE and aRSA or aDSA, so don't worry */
if ( (dh_tmp || dh_rsa || dh_dsa) &&
(rsa_enc || rsa_sign || dsa_sign))
- mask_k|=SSL_kEDH;
+ mask_k|=SSL_kDHE;
if ((dh_tmp_export || dh_rsa_export || dh_dsa_export) &&
(rsa_enc || rsa_sign || dsa_sign))
- emask_k|=SSL_kEDH;
+ emask_k|=SSL_kDHE;
#endif
if (dh_tmp_export)
- emask_k|=SSL_kEDH;
+ emask_k|=SSL_kDHE;
if (dh_tmp)
- mask_k|=SSL_kEDH;
+ mask_k|=SSL_kDHE;
if (dh_rsa) mask_k|=SSL_kDHr;
if (dh_rsa_export) emask_k|=SSL_kDHr;
/* An ECC certificate may be usable for ECDH and/or
* ECDSA cipher suites depending on the key usage extension.
*/
+#ifndef OPENSSL_NO_EC
if (have_ecc_cert)
{
cpk = &c->pkeys[SSL_PKEY_ECC];
}
#endif
}
+#endif
#ifndef OPENSSL_NO_ECDH
if (have_ecdh_tmp)
{
- mask_k|=SSL_kEECDH;
- emask_k|=SSL_kEECDH;
+ mask_k|=SSL_kECDHE;
+ emask_k|=SSL_kECDHE;
}
#endif
int i;
c = s->cert;
+ if (!s->s3 || !s->s3->tmp.new_cipher)
+ return NULL;
ssl_set_cert_masks(c, s->s3->tmp.new_cipher);
#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL
}
#ifndef OPENSSL_NO_TLSEXT
-unsigned char *ssl_get_authz_data(SSL *s, size_t *authz_length)
+int ssl_get_server_cert_serverinfo(SSL *s, const unsigned char **serverinfo,
+ size_t *serverinfo_length)
{
- CERT *c;
- int i;
+ CERT *c = NULL;
+ int i = 0;
+ *serverinfo_length = 0;
c = s->cert;
i = ssl_get_server_cert_index(s);
if (i == -1)
- return NULL;
-
- *authz_length = 0;
- if (c->pkeys[i].authz == NULL)
- return(NULL);
- *authz_length = c->pkeys[i].authz_length;
+ return 0;
+ if (c->pkeys[i].serverinfo == NULL)
+ return 0;
- return c->pkeys[i].authz;
+ *serverinfo = c->pkeys[i].serverinfo;
+ *serverinfo_length = c->pkeys[i].serverinfo_length;
+ return 1;
}
#endif
}
}
+const SSL_METHOD *SSL_CTX_get_ssl_method(SSL_CTX *ctx)
+ {
+ return ctx->method;
+ }
+
const SSL_METHOD *SSL_get_ssl_method(SSL *s)
{
return(s->method);
#endif
}
-/* Fix this function so that it takes an optional type parameter */
X509 *SSL_get_certificate(const SSL *s)
{
if (s->cert != NULL)
return(NULL);
}
-/* Fix this function so that it takes an optional type parameter */
-EVP_PKEY *SSL_get_privatekey(SSL *s)
+EVP_PKEY *SSL_get_privatekey(const SSL *s)
{
if (s->cert != NULL)
return(s->cert->key->privatekey);
return(NULL);
}
+X509 *SSL_CTX_get0_certificate(const SSL_CTX *ctx)
+ {
+ if (ctx->cert != NULL)
+ return ctx->cert->key->x509;
+ else
+ return NULL;
+ }
+
+EVP_PKEY *SSL_CTX_get0_privatekey(const SSL_CTX *ctx)
+ {
+ if (ctx->cert != NULL)
+ return ctx->cert->key->privatekey;
+ else
+ return NULL ;
+ }
+
const SSL_CIPHER *SSL_get_current_cipher(const SSL *s)
{
if ((s->session != NULL) && (s->session->cipher != NULL))
return s->server;
}
+void SSL_set_security_level(SSL *s, int level)
+ {
+ s->cert->sec_level = level;
+ }
+
+int SSL_get_security_level(const SSL *s)
+ {
+ return s->cert->sec_level;
+ }
+
+void SSL_set_security_callback(SSL *s, int (*cb)(SSL *s, SSL_CTX *ctx, int op, int bits, int nid, void *other, void *ex))
+ {
+ s->cert->sec_cb = cb;
+ }
+
+int (*SSL_get_security_callback(const SSL *s))(SSL *s, SSL_CTX *ctx, int op, int bits, int nid, void *other, void *ex)
+ {
+ return s->cert->sec_cb;
+ }
+
+void SSL_set0_security_ex_data(SSL *s, void *ex)
+ {
+ s->cert->sec_ex = ex;
+ }
+
+void *SSL_get0_security_ex_data(const SSL *s)
+ {
+ return s->cert->sec_ex;
+ }
+
+void SSL_CTX_set_security_level(SSL_CTX *ctx, int level)
+ {
+ ctx->cert->sec_level = level;
+ }
+
+int SSL_CTX_get_security_level(const SSL_CTX *ctx)
+ {
+ return ctx->cert->sec_level;
+ }
+
+void SSL_CTX_set_security_callback(SSL_CTX *ctx, int (*cb)(SSL *s, SSL_CTX *ctx, int op, int bits, int nid, void *other, void *ex))
+ {
+ ctx->cert->sec_cb = cb;
+ }
+
+int (*SSL_CTX_get_security_callback(const SSL_CTX *ctx))(SSL *s, SSL_CTX *ctx, int op, int bits, int nid, void *other, void *ex)
+ {
+ return ctx->cert->sec_cb;
+ }
+
+void SSL_CTX_set0_security_ex_data(SSL_CTX *ctx, void *ex)
+ {
+ ctx->cert->sec_ex = ex;
+ }
+
+void *SSL_CTX_get0_security_ex_data(const SSL_CTX *ctx)
+ {
+ return ctx->cert->sec_ex;
+ }
+
#if defined(_WINDLL) && defined(OPENSSL_SYS_WIN16)
#include "../crypto/bio/bss_file.c"
#endif