X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=ssl%2Fssl_lib.c;h=7eb1a0cafc088782d709fc41a11b6d167575c28b;hp=b08e82688f23a53c36ffc5a3a9d31aa1c64361e3;hb=2911575c6e790541e495927a60121d7546a66962;hpb=a398f821fa98b9923a426cf45b268cf4d56c89bd diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index b08e82688f..7eb1a0cafc 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -382,6 +382,17 @@ SSL *SSL_new(SSL_CTX *ctx) # 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; @@ -606,6 +617,8 @@ void SSL_free(SSL *s) 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) @@ -1173,8 +1186,10 @@ long SSL_CTX_ctrl(SSL_CTX *ctx,int cmd,long larg,void *parg) { 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); @@ -1581,7 +1596,6 @@ int SSL_get_servername_type(const SSL *s) 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. @@ -1648,6 +1662,7 @@ int SSL_select_next_proto(unsigned char **out, unsigned char *outlen, const unsi 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. @@ -1702,16 +1717,17 @@ int SSL_CTX_set_custom_cli_ext(SSL_CTX *ctx, unsigned short ext_type, custom_cli_ext_first_cb_fn fn1, custom_cli_ext_second_cb_fn fn2, void* arg) { - /* Check for duplicates */ size_t i; custom_cli_ext_record* record; + /* Check for duplicates */ for (i=0; i < ctx->custom_cli_ext_records_count; i++) if (ext_type == ctx->custom_cli_ext_records[i].ext_type) return 0; ctx->custom_cli_ext_records = OPENSSL_realloc(ctx->custom_cli_ext_records, - (ctx->custom_cli_ext_records_count+1) * sizeof(custom_cli_ext_record)); + (ctx->custom_cli_ext_records_count + 1) * + sizeof(custom_cli_ext_record)); if (!ctx->custom_cli_ext_records) { ctx->custom_cli_ext_records_count = 0; return 0; @@ -1726,19 +1742,20 @@ int SSL_CTX_set_custom_cli_ext(SSL_CTX *ctx, unsigned short ext_type, } int SSL_CTX_set_custom_srv_ext(SSL_CTX *ctx, unsigned short ext_type, - custom_srv_ext_first_cb_fn fn1, - custom_srv_ext_second_cb_fn fn2, void* arg) + custom_srv_ext_first_cb_fn fn1, + custom_srv_ext_second_cb_fn fn2, void* arg) { - /* Check for duplicates */ size_t i; custom_srv_ext_record* record; + /* Check for duplicates */ for (i=0; i < ctx->custom_srv_ext_records_count; i++) if (ext_type == ctx->custom_srv_ext_records[i].ext_type) return 0; ctx->custom_srv_ext_records = OPENSSL_realloc(ctx->custom_srv_ext_records, - (ctx->custom_srv_ext_records_count+1) * sizeof(custom_srv_ext_record)); + (ctx->custom_srv_ext_records_count + 1) * + sizeof(custom_srv_ext_record)); if (!ctx->custom_srv_ext_records) { ctx->custom_srv_ext_records_count = 0; return 0; @@ -1752,7 +1769,138 @@ int SSL_CTX_set_custom_srv_ext(SSL_CTX *ctx, unsigned short ext_type, return 1; } -#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; + } + +int SSL_CTX_set_cli_supp_data(SSL_CTX *ctx, + unsigned short supp_data_type, + cli_supp_data_first_cb_fn fn1, + cli_supp_data_second_cb_fn fn2, void* arg) + { + size_t i; + cli_supp_data_record* record; + + /* Check for duplicates */ + for (i=0; i < ctx->cli_supp_data_records_count; i++) + if (supp_data_type == ctx->cli_supp_data_records[i].supp_data_type) + return 0; + + ctx->cli_supp_data_records = OPENSSL_realloc(ctx->cli_supp_data_records, + (ctx->cli_supp_data_records_count+1) * sizeof(cli_supp_data_record)); + if (!ctx->cli_supp_data_records) + { + ctx->cli_supp_data_records_count = 0; + return 0; + } + ctx->cli_supp_data_records_count++; + record = &ctx->cli_supp_data_records[ctx->cli_supp_data_records_count - 1]; + record->supp_data_type = supp_data_type; + record->fn1 = fn1; + record->fn2 = fn2; + record->arg = arg; + return 1; + } + +int SSL_CTX_set_srv_supp_data(SSL_CTX *ctx, + unsigned short supp_data_type, + srv_supp_data_first_cb_fn fn1, + srv_supp_data_second_cb_fn fn2, void* arg) + { + size_t i; + srv_supp_data_record* record; + + /* Check for duplicates */ + for (i=0; i < ctx->srv_supp_data_records_count; i++) + if (supp_data_type == ctx->srv_supp_data_records[i].supp_data_type) + return 0; + + ctx->srv_supp_data_records = OPENSSL_realloc(ctx->srv_supp_data_records, + (ctx->srv_supp_data_records_count+1) * sizeof(srv_supp_data_record)); + if (!ctx->srv_supp_data_records) + { + ctx->srv_supp_data_records_count = 0; + return 0; + } + ctx->srv_supp_data_records_count++; + record = &ctx->srv_supp_data_records[ctx->srv_supp_data_records_count - 1]; + record->supp_data_type = supp_data_type; + record->fn1 = fn1; + record->fn2 = fn2; + record->arg = arg; + + return 1; + } + +#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, @@ -1955,6 +2103,10 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) ret->custom_cli_ext_records_count = 0; ret->custom_srv_ext_records = NULL; ret->custom_srv_ext_records_count = 0; + ret->cli_supp_data_records = NULL; + ret->cli_supp_data_records_count = 0; + ret->srv_supp_data_records = NULL; + ret->srv_supp_data_records_count = 0; #ifndef OPENSSL_NO_BUF_FREELISTS ret->freelist_max_len = SSL_MAX_BUF_FREELIST_LEN_DEFAULT; ret->rbuf_freelist = OPENSSL_malloc(sizeof(SSL3_BUF_FREELIST)); @@ -2096,6 +2248,8 @@ void SSL_CTX_free(SSL_CTX *a) #ifndef OPENSSL_NO_TLSEXT OPENSSL_free(a->custom_cli_ext_records); OPENSSL_free(a->custom_srv_ext_records); + OPENSSL_free(a->cli_supp_data_records); + OPENSSL_free(a->srv_supp_data_records); #endif #ifndef OPENSSL_NO_ENGINE if (a->client_cert_engine) @@ -2115,6 +2269,8 @@ void SSL_CTX_free(SSL_CTX *a) 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); @@ -2164,14 +2320,17 @@ void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher) 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); @@ -2209,7 +2368,9 @@ void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher) 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; @@ -2289,6 +2450,7 @@ void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher) /* 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]; @@ -2345,6 +2507,7 @@ void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher) } #endif } +#endif #ifndef OPENSSL_NO_ECDH if (have_ecdh_tmp) @@ -2524,25 +2687,6 @@ EVP_PKEY *ssl_get_sign_pkey(SSL *s,const SSL_CIPHER *cipher, const EVP_MD **pmd) } #ifndef OPENSSL_NO_TLSEXT -unsigned char *ssl_get_authz_data(SSL *s, size_t *authz_length) - { - CERT *c; - int i; - - 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 c->pkeys[i].authz; - } - int ssl_get_server_cert_serverinfo(SSL *s, const unsigned char **serverinfo, size_t *serverinfo_length) {