/** * gnutls_dh_params_init: * @dh_params: Is a structure that will hold the prime numbers * * This function will initialize the DH parameters structure. * * Returns: On success, %GNUTLS_E_SUCCESS (zero) is returned, * otherwise an error code is returned. **/ int gnutls_dh_params_init (gnutls_dh_params_t * dh_params) { (*dh_params) = gnutls_calloc (1, sizeof (dh_params_st)); if (*dh_params == NULL) { gnutls_assert (); return GNUTLS_E_MEMORY_ERROR; } return 0; }
/** * gnutls_x509_privkey_init: * @key: The structure to be initialized * * This function will initialize an private key structure. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. **/ int gnutls_x509_privkey_init (gnutls_x509_privkey_t * key) { *key = gnutls_calloc (1, sizeof (gnutls_x509_privkey_int)); if (*key) { (*key)->key = ASN1_TYPE_EMPTY; (*key)->pk_algorithm = GNUTLS_PK_UNKNOWN; return 0; /* success */ } return GNUTLS_E_MEMORY_ERROR; }
/** * gnutls_certificate_allocate_credentials - Used to allocate a gnutls_certificate_credentials_t structure * @res: is a pointer to an #gnutls_certificate_credentials_t structure. * * This structure is complex enough to manipulate directly thus this * helper function is provided in order to allocate it. * * Returns: %GNUTLS_E_SUCCESS on success, or an error code. **/ int gnutls_certificate_allocate_credentials (gnutls_certificate_credentials_t * res) { *res = gnutls_calloc (1, sizeof (certificate_credentials_st)); if (*res == NULL) return GNUTLS_E_MEMORY_ERROR; (*res)->verify_bits = DEFAULT_VERIFY_BITS; (*res)->verify_depth = DEFAULT_VERIFY_DEPTH; return 0; }
/* This function will create the auth info structure in the key * structure if needed. * * If allow change is !=0 then this will allow changing the auth * info structure to a different type. */ int _gnutls_auth_info_set(gnutls_session_t session, gnutls_credentials_type_t type, int size, int allow_change) { if (session->key.auth_info == NULL) { session->key.auth_info = gnutls_calloc(1, size); if (session->key.auth_info == NULL) { gnutls_assert(); return GNUTLS_E_MEMORY_ERROR; } session->key.auth_info_type = type; session->key.auth_info_size = size; } else { if (allow_change == 0) { /* If the credentials for the current authentication scheme, * are not the one we want to set, then it's an error. * This may happen if a rehandshake is performed an the * ciphersuite which is negotiated has different authentication * schema. */ if (type != session->key.auth_info_type) { gnutls_assert(); return GNUTLS_E_INVALID_REQUEST; } } else { /* The new behaviour: Here we reallocate the auth info structure * in order to be able to negotiate different authentication * types. Ie. perform an auth_anon and then authenticate again using a * certificate (in order to prevent revealing the certificate's contents, * to passive eavesdropers. */ if (type != session->key.auth_info_type) { _gnutls_free_auth_info(session); session->key.auth_info = calloc(1, size); if (session->key.auth_info == NULL) { gnutls_assert(); return GNUTLS_E_MEMORY_ERROR; } session->key.auth_info_type = type; session->key.auth_info_size = size; } } } return 0; }
/** * gnutls_pkcs12_init: * @pkcs12: A pointer to the type to be initialized * * This function will initialize a PKCS12 type. PKCS12 structures * usually contain lists of X.509 Certificates and X.509 Certificate * revocation lists. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. **/ int gnutls_pkcs12_init(gnutls_pkcs12_t * pkcs12) { *pkcs12 = gnutls_calloc(1, sizeof(gnutls_pkcs12_int)); if (*pkcs12) { int result = pkcs12_reinit(*pkcs12); if (result < 0) { gnutls_assert(); gnutls_free(*pkcs12); return result; } return 0; /* success */ } return GNUTLS_E_MEMORY_ERROR; }
/* This calculates the SHA1(A | B) * A and B will be left-padded with zeros to fill n_size. */ bigint_t _gnutls_calc_srp_u(bigint_t A, bigint_t B, bigint_t n) { size_t b_size, a_size; uint8_t *holder, hd[MAX_HASH_SIZE]; size_t holder_size, hash_size, n_size; int ret; bigint_t res; /* get the size of n in bytes */ _gnutls_mpi_print(n, NULL, &n_size); _gnutls_mpi_print(A, NULL, &a_size); _gnutls_mpi_print(B, NULL, &b_size); if (a_size > n_size || b_size > n_size) { gnutls_assert(); return NULL; /* internal error */ } holder_size = n_size + n_size; holder = gnutls_calloc(1, holder_size); if (holder == NULL) return NULL; _gnutls_mpi_print(A, &holder[n_size - a_size], &a_size); _gnutls_mpi_print(B, &holder[n_size + n_size - b_size], &b_size); ret = _gnutls_hash_fast(GNUTLS_DIG_SHA1, holder, holder_size, hd); if (ret < 0) { gnutls_free(holder); gnutls_assert(); return NULL; } /* convert the bytes of hd to integer */ hash_size = 20; /* SHA */ ret = _gnutls_mpi_init_scan_nz(&res, hd, hash_size); gnutls_free(holder); if (ret < 0) { gnutls_assert(); return NULL; } return res; }
/** * gnutls_x509_dn_init: * @dn: the object to be initialized * * This function initializes a #gnutls_x509_dn_t type. * * The object returned must be deallocated using * gnutls_x509_dn_deinit(). * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. * * Since: 2.4.0 **/ int gnutls_x509_dn_init(gnutls_x509_dn_t * dn) { int result; *dn = gnutls_calloc(1, sizeof(gnutls_x509_dn_st)); if ((result = asn1_create_element(_gnutls_get_pkix(), "PKIX1.Name", &(*dn)->asn)) != ASN1_SUCCESS) { gnutls_assert(); gnutls_free(*dn); return _gnutls_asn2err(result); } return 0; }
/* Parses the Signature Algorithm structure and stores data into * session->security_parameters.extensions. */ int _gnutls_sign_algorithm_parse_data(gnutls_session_t session, const uint8_t * data, size_t data_size) { unsigned int sig, i; sig_ext_st *priv; extension_priv_data_t epriv; if (data_size % 2 != 0) return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH); priv = gnutls_calloc(1, sizeof(*priv)); if (priv == NULL) { gnutls_assert(); return GNUTLS_E_MEMORY_ERROR; } for (i = 0; i < data_size; i += 2) { sign_algorithm_st aid; aid.hash_algorithm = data[i]; aid.sign_algorithm = data[i + 1]; sig = _gnutls_tls_aid_to_sign(&aid); _gnutls_handshake_log ("EXT[%p]: rcvd signature algo (%d.%d) %s\n", session, aid.hash_algorithm, aid.sign_algorithm, gnutls_sign_get_name(sig)); if (sig != GNUTLS_SIGN_UNKNOWN) { priv->sign_algorithms[priv-> sign_algorithms_size++] = sig; if (priv->sign_algorithms_size == MAX_SIGNATURE_ALGORITHMS) break; } } epriv = priv; _gnutls_ext_set_session_data(session, GNUTLS_EXTENSION_SIGNATURE_ALGORITHMS, epriv); return 0; }
/** * gnutls_pkcs12_init: * @pkcs12: The structure to be initialized * * This function will initialize a PKCS12 structure. PKCS12 structures * usually contain lists of X.509 Certificates and X.509 Certificate * revocation lists. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. **/ int gnutls_pkcs12_init(gnutls_pkcs12_t * pkcs12) { *pkcs12 = gnutls_calloc(1, sizeof(gnutls_pkcs12_int)); if (*pkcs12) { int result = asn1_create_element(_gnutls_get_pkix(), "PKIX1.pkcs-12-PFX", &(*pkcs12)->pkcs12); if (result != ASN1_SUCCESS) { gnutls_assert(); gnutls_free(*pkcs12); return _gnutls_asn2err(result); } return 0; /* success */ } return GNUTLS_E_MEMORY_ERROR; }
/** * gnutls_x509_crl_init: * @crl: The structure to be initialized * * This function will initialize a CRL structure. CRL stands for * Certificate Revocation List. A revocation list usually contains * lists of certificate serial numbers that have been revoked by an * Authority. The revocation lists are always signed with the * authority's private key. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. **/ int gnutls_x509_crl_init(gnutls_x509_crl_t * crl) { FAIL_IF_LIB_ERROR; *crl = gnutls_calloc(1, sizeof(gnutls_x509_crl_int)); if (*crl) { int result = crl_reinit(*crl); if (result < 0) { gnutls_assert(); gnutls_free(*crl); return result; } return 0; /* success */ } return GNUTLS_E_MEMORY_ERROR; }
static int aes_gcm_cipher_init(gnutls_cipher_algorithm_t algorithm, void **_ctx, int enc) { /* we use key size to distinguish */ if (algorithm != GNUTLS_CIPHER_AES_128_GCM && algorithm != GNUTLS_CIPHER_AES_256_GCM) return GNUTLS_E_INVALID_REQUEST; *_ctx = gnutls_calloc(1, sizeof(struct gcm_x86_aes_ctx)); if (*_ctx == NULL) { gnutls_assert(); return GNUTLS_E_MEMORY_ERROR; } return 0; }
/** * gnutls_x509_crl_init: * @crl: The structure to be initialized * * This function will initialize a CRL structure. CRL stands for * Certificate Revocation List. A revocation list usually contains * lists of certificate serial numbers that have been revoked by an * Authority. The revocation lists are always signed with the * authority's private key. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. **/ int gnutls_x509_crl_init(gnutls_x509_crl_t * crl) { *crl = gnutls_calloc(1, sizeof(gnutls_x509_crl_int)); if (*crl) { int result = asn1_create_element(_gnutls_get_pkix(), "PKIX1.CertificateList", &(*crl)->crl); if (result != ASN1_SUCCESS) { gnutls_assert(); gnutls_free(*crl); return _gnutls_asn2err(result); } return 0; /* success */ } return GNUTLS_E_MEMORY_ERROR; }
/** * gnutls_system_key_iter_get_info: * @iter: an iterator of the system keys (must be set to %NULL initially) * @cert_type: A value of gnutls_certificate_type_t which indicates the type of certificate to look for * @cert_url: The certificate URL of the pair (may be %NULL) * @key_url: The key URL of the pair (may be %NULL) * @label: The friendly name (if any) of the pair (may be %NULL) * @der: if non-NULL the DER data of the certificate * @flags: should be zero * * This function will return on each call a certificate * and key pair URLs, as well as a label associated with them, * and the DER-encoded certificate. When the iteration is complete it will * return %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE. * * Typically @cert_type should be %GNUTLS_CRT_X509. * * All values set are allocated and must be cleared using gnutls_free(), * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. * * Since: 3.4.0 **/ int gnutls_system_key_iter_get_info(gnutls_system_key_iter_t * iter, unsigned cert_type, char **cert_url, char **key_url, char **label, gnutls_datum_t * der, unsigned int flags) { if (ncrypt_init == 0) return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE); if (cert_type != GNUTLS_CRT_X509) return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE); if (*iter == NULL) { *iter = gnutls_calloc(1, sizeof(struct system_key_iter_st)); if (*iter == NULL) return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); (*iter)->store = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0, CERT_SYSTEM_STORE_CURRENT_USER, L"MY"); if ((*iter)->store == NULL) { gnutls_free(*iter); *iter = NULL; return gnutls_assert_val (GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE); } (*iter)->cert = CertEnumCertificatesInStore((*iter)->store, NULL); return get_win_urls((*iter)->cert, cert_url, key_url, label, der); } else { if ((*iter)->cert == NULL) return gnutls_assert_val (GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE); (*iter)->cert = CertEnumCertificatesInStore((*iter)->store, (*iter)->cert); return get_win_urls((*iter)->cert, cert_url, key_url, label, der); } }
static int aes_cipher_init(gnutls_cipher_algorithm_t algorithm, void **_ctx, int enc) { /* we use key size to distinguish */ if (algorithm != GNUTLS_CIPHER_AES_128_CBC && algorithm != GNUTLS_CIPHER_AES_192_CBC && algorithm != GNUTLS_CIPHER_AES_256_CBC) return GNUTLS_E_INVALID_REQUEST; *_ctx = gnutls_calloc(1, sizeof(struct padlock_ctx)); if (*_ctx == NULL) { gnutls_assert(); return GNUTLS_E_MEMORY_ERROR; } ((struct padlock_ctx *) (*_ctx))->enc = enc; return 0; }
/** * gnutls_alpn_set_protocols: * @session: is a #gnutls_session_t structure. * @protocols: is the protocol names to add. * @protocols_size: the number of protocols to add. * @flags: zero or %GNUTLS_ALPN_* * * This function is to be used by both clients and servers, to declare * the supported ALPN protocols, which are used during peer negotiation. * * If %GNUTLS_ALPN_MAND is specified the connection will be aborted * if no matching ALPN protocol is found. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, * otherwise a negative error code is returned. * * Since 3.1.11 **/ int gnutls_alpn_set_protocols (gnutls_session_t session, const gnutls_datum_t * protocols, unsigned protocols_size, unsigned int flags) { int ret; alpn_ext_st *priv; extension_priv_data_t epriv; unsigned i; ret = _gnutls_ext_get_session_data (session, GNUTLS_EXTENSION_ALPN, &epriv); if (ret < 0) { priv = gnutls_calloc (1, sizeof (*priv)); if (priv == NULL) { gnutls_assert (); return GNUTLS_E_MEMORY_ERROR; } epriv.ptr = priv; _gnutls_ext_set_session_data (session, GNUTLS_EXTENSION_ALPN, epriv); } else priv = epriv.ptr; if (protocols_size > MAX_ALPN_PROTOCOLS) return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); for (i=0;i<protocols_size;i++) { if (protocols[i].size >= MAX_ALPN_PROTOCOL_NAME) return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); memcpy(priv->protocols[i], protocols[i].data, protocols[i].size); priv->protocol_size[i] = protocols[i].size; priv->size++; } priv->flags = flags; return 0; }
/** * gnutls_pkcs11_privkey_init: * @key: The structure to be initialized * * This function will initialize an private key structure. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. **/ int gnutls_pkcs11_privkey_init(gnutls_pkcs11_privkey_t * key) { FAIL_IF_LIB_ERROR; *key = gnutls_calloc(1, sizeof(struct gnutls_pkcs11_privkey_st)); if (*key == NULL) { gnutls_assert(); return GNUTLS_E_MEMORY_ERROR; } (*key)->info = p11_kit_uri_new(); if ((*key)->info == NULL) { free(*key); gnutls_assert(); return GNUTLS_E_MEMORY_ERROR; } return 0; }
/* if a server received the special ciphersuite. */ int _gnutls_ext_sr_recv_cs (gnutls_session_t session) { int ret, set = 0; sr_ext_st *priv; extension_priv_data_t epriv; ret = _gnutls_ext_get_session_data (session, GNUTLS_EXTENSION_SAFE_RENEGOTIATION, &epriv); if (ret < 0) { set = 1; } else if (ret < 0) { gnutls_assert (); return ret; } if (set != 0) { priv = gnutls_calloc (1, sizeof (*priv)); if (priv == NULL) { gnutls_assert (); return GNUTLS_E_MEMORY_ERROR; } epriv.ptr = priv; } else priv = epriv.ptr; priv->safe_renegotiation_received = 1; priv->connection_using_safe_renegotiation = 1; if (set != 0) _gnutls_ext_set_session_data (session, GNUTLS_EXTENSION_SAFE_RENEGOTIATION, epriv); return 0; }
/** * gnutls_tpm_get_registered: * @list: a list to store the keys * * This function will get a list of stored keys in the TPM. The uuid * of those keys * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. * * Since: 3.1.0 **/ int gnutls_tpm_get_registered(gnutls_tpm_key_list_t * list) { TSS_RESULT tssret; int ret; CHECK_INIT; *list = gnutls_calloc(1, sizeof(struct tpm_key_list_st)); if (*list == NULL) return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); tssret = pTspi_Context_Create(&(*list)->tpm_ctx); if (tssret) { gnutls_assert(); ret = tss_err(tssret); goto cleanup; } tssret = pTspi_Context_Connect((*list)->tpm_ctx, NULL); if (tssret) { gnutls_assert(); ret = tss_err(tssret); goto cleanup; } tssret = pTspi_Context_GetRegisteredKeysByUUID2((*list)->tpm_ctx, TSS_PS_TYPE_SYSTEM, NULL, &(*list)->size, &(*list)->ki); if (tssret) { gnutls_assert(); ret = tss_err(tssret); goto cleanup; } return 0; cleanup: gnutls_tpm_key_list_deinit(*list); return ret; }
static int aes_gcm_cipher_init(gnutls_cipher_algorithm_t algorithm, void **_ctx, int enc) { struct cryptodev_gcm_ctx *ctx; *_ctx = gnutls_calloc(1, sizeof(struct cryptodev_gcm_ctx)); if (*_ctx == NULL) { gnutls_assert(); return GNUTLS_E_MEMORY_ERROR; } ctx = *_ctx; ctx->cfd = _gnutls_cryptodev_fd; ctx->sess.cipher = cipher_map[algorithm]; ctx->cryp.iv = ctx->iv; return 0; }
static int wrap_x86_hmac_init(gnutls_mac_algorithm_t algo, void **_ctx) { struct x86_hmac_ctx *ctx; int ret; ctx = gnutls_calloc(1, sizeof(struct x86_hmac_ctx)); if (ctx == NULL) { gnutls_assert(); return GNUTLS_E_MEMORY_ERROR; } ctx->algo = algo; ret = _hmac_ctx_init(algo, ctx); if (ret < 0) return gnutls_assert_val(ret); *_ctx = ctx; return 0; }
static int _gnutls_server_name_unpack (gnutls_buffer_st * ps, extension_priv_data_t * _priv) { server_name_ext_st *priv; unsigned int i; int ret; extension_priv_data_t epriv; priv = gnutls_calloc (1, sizeof (*priv)); if (priv == NULL) { gnutls_assert (); return GNUTLS_E_MEMORY_ERROR; } BUFFER_POP_NUM (ps, priv->server_names_size); for (i = 0; i < priv->server_names_size; i++) { BUFFER_POP_NUM (ps, priv->server_names[i].type); BUFFER_POP_NUM (ps, priv->server_names[i].name_length); if (priv->server_names[i].name_length > sizeof (priv->server_names[i].name)) { gnutls_assert (); return GNUTLS_E_PARSING_ERROR; } BUFFER_POP (ps, priv->server_names[i].name, priv->server_names[i].name_length); } epriv.ptr = priv; *_priv = epriv; return 0; error: gnutls_free (priv); return ret; }
static int _proxyinfo_unpack (gnutls_buffer_st * ps, extension_priv_data_t * _priv) { // Read the internal state from buffer ProxyInfo_ext_st *priv; int i, ret; extension_priv_data_t epriv; priv = gnutls_calloc (1, sizeof (*priv)); if (priv == NULL) { gnutls_assert (); return GNUTLS_E_MEMORY_ERROR; } // BUFFER_POP_NUM (ps, priv->proxy_cnt); /* BUFFER_POP_NUM (ps, priv->server_names_size); for (i = 0; i < priv->server_names_size; i++) { BUFFER_POP_NUM (ps, priv->server_names[i].type); BUFFER_POP_NUM (ps, priv->server_names[i].name_length); if (priv->server_names[i].name_length > sizeof (priv->server_names[i].name)) { gnutls_assert (); return GNUTLS_E_PARSING_ERROR; } BUFFER_POP (ps, priv->server_names[i].name, priv->server_names[i].name_length); } */ epriv.ptr = priv; *_priv = epriv; return 0; error: gnutls_free (priv); return ret; }
static int _gnutls_status_request_unpack(gnutls_buffer_st * ps, extension_priv_data_t * epriv) { status_request_ext_st *priv; int ret; priv = gnutls_calloc(1, sizeof(*priv)); if (priv == NULL) { gnutls_assert(); return GNUTLS_E_MEMORY_ERROR; } BUFFER_POP_DATUM(ps, &priv->response); epriv->ptr = priv; return 0; error: gnutls_free(priv); return ret; }
/** * gnutls_certificate_allocate_credentials: * @res: is a pointer to a #gnutls_certificate_credentials_t structure. * * This structure is complex enough to manipulate directly thus this * helper function is provided in order to allocate it. * * Returns: %GNUTLS_E_SUCCESS on success, or an error code. **/ int gnutls_certificate_allocate_credentials (gnutls_certificate_credentials_t * res) { int ret; *res = gnutls_calloc (1, sizeof (certificate_credentials_st)); if (*res == NULL) return GNUTLS_E_MEMORY_ERROR; ret = gnutls_x509_trust_list_init( &(*res)->tlist, 0); if (ret < 0) { gnutls_assert(); gnutls_free(*res); return GNUTLS_E_MEMORY_ERROR; } (*res)->verify_bits = DEFAULT_MAX_VERIFY_BITS; (*res)->verify_depth = DEFAULT_MAX_VERIFY_DEPTH; return 0; }
int _gnutls_ext_sr_send_cs (gnutls_session_t session) { int ret, set = 0; sr_ext_st *priv; extension_priv_data_t epriv; ret = _gnutls_ext_get_session_data (session, GNUTLS_EXTENSION_SAFE_RENEGOTIATION, &epriv); if (ret < 0) { set = 1; } else if (ret < 0) { gnutls_assert (); return ret; } if (set != 0) { priv = gnutls_calloc (1, sizeof (*priv)); if (priv == NULL) { gnutls_assert (); return GNUTLS_E_MEMORY_ERROR; } epriv.ptr = priv; } if (set != 0) _gnutls_ext_set_session_data (session, GNUTLS_EXTENSION_SAFE_RENEGOTIATION, epriv); return 0; }
int _gnutls_epoch_alloc(gnutls_session_t session, uint16_t epoch, record_parameters_st ** out) { record_parameters_st **slot; _gnutls_record_log("REC[%p]: Allocating epoch #%u\n", session, epoch); slot = epoch_get_slot(session, epoch); /* If slot out of range or not empty. */ if (slot == NULL) return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); if (*slot != NULL) return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); *slot = gnutls_calloc(1, sizeof(record_parameters_st)); if (*slot == NULL) return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); (*slot)->epoch = epoch; (*slot)->cipher = NULL; (*slot)->mac = NULL; (*slot)->compression_algorithm = GNUTLS_COMP_UNKNOWN; if (IS_DTLS(session)) _gnutls_write_uint16(epoch, UINT64DATA((*slot)->write. sequence_number)); if (out != NULL) *out = *slot; return 0; }
/* Parses the Signature Algorithm structure and stores data into * session->security_parameters.extensions. */ int _gnutls_sign_algorithm_parse_data (gnutls_session_t session, const opaque * data, size_t data_size) { int sig, i; sig_ext_st *priv; extension_priv_data_t epriv; priv = gnutls_calloc (1, sizeof (*priv)); if (priv == NULL) { gnutls_assert (); return GNUTLS_E_MEMORY_ERROR; } for (i = 0; i < data_size; i += 2) { sign_algorithm_st aid; aid.hash_algorithm = data[i]; aid.sign_algorithm = data[i + 1]; sig = _gnutls_tls_aid_to_sign (&aid); if (sig != GNUTLS_SIGN_UNKNOWN) { priv->sign_algorithms[priv->sign_algorithms_size++] = sig; if (priv->sign_algorithms_size == MAX_SIGNATURE_ALGORITHMS) break; } } epriv.ptr = priv; _gnutls_ext_set_session_data (session, GNUTLS_EXTENSION_SIGNATURE_ALGORITHMS, epriv); return 0; }
/** * gnutls_session_ticket_enable_client: * @session: is a #gnutls_session_t type. * * Request that the client should attempt session resumption using * SessionTicket. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, or an * error code. * * Since: 2.10.0 **/ int gnutls_session_ticket_enable_client(gnutls_session_t session) { session_ticket_ext_st *priv = NULL; extension_priv_data_t epriv; if (!session) { gnutls_assert(); return GNUTLS_E_INVALID_REQUEST; } priv = gnutls_calloc(1, sizeof(*priv)); if (priv == NULL) { gnutls_assert(); return GNUTLS_E_MEMORY_ERROR; } priv->session_ticket_enable = 1; epriv = priv; _gnutls_ext_set_session_data(session, GNUTLS_EXTENSION_SESSION_TICKET, epriv); return 0; }
/** * gnutls_priority_init: * @priority_cache: is a #gnutls_prioritity_t structure. * @priorities: is a string describing priorities * @err_pos: In case of an error this will have the position in the string the error occured * * Sets priorities for the ciphers, key exchange methods, macs and * compression methods. * * The #priorities option allows you to specify a colon * separated list of the cipher priorities to enable. * Some keywords are defined to provide quick access * to common preferences. * * Unless there is a special need, using "NORMAL" or "NORMAL:%COMPAT" for compatibility * is recommended. * * "PERFORMANCE" means all the "secure" ciphersuites are enabled, * limited to 128 bit ciphers and sorted by terms of speed * performance. * * "NORMAL" means all "secure" ciphersuites. The 256-bit ciphers are * included as a fallback only. The ciphers are sorted by security * margin. * * "PFS" means all "secure" ciphersuites that support perfect forward secrecy. * The 256-bit ciphers are included as a fallback only. * The ciphers are sorted by security margin. * * "SECURE128" means all "secure" ciphersuites of security level 128-bit * or more. * * "SECURE192" means all "secure" ciphersuites of security level 192-bit * or more. * * "SUITEB128" means all the NSA SuiteB ciphersuites with security level * of 128. * * "SUITEB192" means all the NSA SuiteB ciphersuites with security level * of 192. * * "EXPORT" means all ciphersuites are enabled, including the * low-security 40 bit ciphers. * * "NONE" means nothing is enabled. This disables even protocols and * compression methods. * * Special keywords are "!", "-" and "+". * "!" or "-" appended with an algorithm will remove this algorithm. * "+" appended with an algorithm will add this algorithm. * * Check the GnuTLS manual section "Priority strings" for detailed * information. * * Examples: * * "NONE:+VERS-TLS-ALL:+MAC-ALL:+RSA:+AES-128-CBC:+SIGN-ALL:+COMP-NULL" * * "NORMAL:-ARCFOUR-128" means normal ciphers except for ARCFOUR-128. * * "SECURE128:-VERS-SSL3.0:+COMP-DEFLATE" means that only secure ciphers are * enabled, SSL3.0 is disabled, and libz compression enabled. * * "NONE:+VERS-TLS-ALL:+AES-128-CBC:+RSA:+SHA1:+COMP-NULL:+SIGN-RSA-SHA1", * * "NONE:+VERS-TLS-ALL:+AES-128-CBC:+ECDHE-RSA:+SHA1:+COMP-NULL:+SIGN-RSA-SHA1:+CURVE-SECP256R1", * * "SECURE256:+SECURE128", * * Note that "NORMAL:%COMPAT" is the most compatible mode. * * Returns: On syntax error %GNUTLS_E_INVALID_REQUEST is returned, * %GNUTLS_E_SUCCESS on success, or an error code. **/ int gnutls_priority_init(gnutls_priority_t * priority_cache, const char *priorities, const char **err_pos) { char *broken_list[MAX_ELEMENTS]; int broken_list_size = 0, i = 0, j; char *darg = NULL; unsigned ikeyword_set = 0; int algo; rmadd_func *fn; bulk_rmadd_func *bulk_fn; *priority_cache = gnutls_calloc(1, sizeof(struct gnutls_priority_st)); if (*priority_cache == NULL) { gnutls_assert(); return GNUTLS_E_MEMORY_ERROR; } if (err_pos) *err_pos = priorities; /* for now unsafe renegotiation is default on everyone. To be removed * when we make it the default. */ (*priority_cache)->sr = SR_PARTIAL; (*priority_cache)->ssl3_record_version = 1; (*priority_cache)->max_empty_records = DEFAULT_MAX_EMPTY_RECORDS; if (priorities == NULL) priorities = LEVEL_NORMAL; darg = gnutls_strdup(priorities); if (darg == NULL) { gnutls_assert(); goto error; } break_comma_list(darg, broken_list, &broken_list_size, MAX_ELEMENTS, ':'); /* This is our default set of protocol version, certificate types and * compression methods. */ if (strcasecmp(broken_list[0], LEVEL_NONE) != 0) { _set_priority(&(*priority_cache)->protocol, protocol_priority); _set_priority(&(*priority_cache)->compression, comp_priority); _set_priority(&(*priority_cache)->cert_type, cert_type_priority_default); _set_priority(&(*priority_cache)->sign_algo, sign_priority_default); _set_priority(&(*priority_cache)->supported_ecc, supported_ecc_normal); i = 0; } else { ikeyword_set = 1; i = 1; } for (; i < broken_list_size; i++) { if (check_level(broken_list[i], *priority_cache, ikeyword_set) != 0) { ikeyword_set = 1; continue; } else if (broken_list[i][0] == '!' || broken_list[i][0] == '+' || broken_list[i][0] == '-') { if (broken_list[i][0] == '+') { fn = prio_add; bulk_fn = _add_priority; } else { fn = prio_remove; bulk_fn = _clear_priorities; } if (broken_list[i][0] == '+' && check_level(&broken_list[i][1], *priority_cache, 1) != 0) { continue; } else if ((algo = gnutls_mac_get_id(&broken_list[i][1])) != GNUTLS_MAC_UNKNOWN) fn(&(*priority_cache)->mac, algo); else if ((algo = gnutls_cipher_get_id(&broken_list[i][1])) != GNUTLS_CIPHER_UNKNOWN) fn(&(*priority_cache)->cipher, algo); else if ((algo = gnutls_kx_get_id(&broken_list[i][1])) != GNUTLS_KX_UNKNOWN) fn(&(*priority_cache)->kx, algo); else if (strncasecmp (&broken_list[i][1], "VERS-", 5) == 0) { if (strncasecmp (&broken_list[i][1], "VERS-TLS-ALL", 12) == 0) { bulk_fn(&(*priority_cache)-> protocol, protocol_priority); } else if (strncasecmp (&broken_list[i][1], "VERS-DTLS-ALL", 13) == 0) { bulk_fn(&(*priority_cache)-> protocol, dtls_protocol_priority); } else { if ((algo = gnutls_protocol_get_id (&broken_list[i][6])) != GNUTLS_VERSION_UNKNOWN) fn(&(*priority_cache)-> protocol, algo); else goto error; } } /* now check if the element is something like -ALGO */ else if (strncasecmp (&broken_list[i][1], "COMP-", 5) == 0) { if (strncasecmp (&broken_list[i][1], "COMP-ALL", 8) == 0) { bulk_fn(&(*priority_cache)-> compression, comp_priority); } else { if ((algo = gnutls_compression_get_id (&broken_list[i][6])) != GNUTLS_COMP_UNKNOWN) fn(&(*priority_cache)-> compression, algo); else goto error; } } /* now check if the element is something like -ALGO */ else if (strncasecmp (&broken_list[i][1], "CURVE-", 6) == 0) { if (strncasecmp (&broken_list[i][1], "CURVE-ALL", 9) == 0) { bulk_fn(&(*priority_cache)-> supported_ecc, supported_ecc_normal); } else { if ((algo = _gnutls_ecc_curve_get_id (&broken_list[i][7])) != GNUTLS_ECC_CURVE_INVALID) fn(&(*priority_cache)-> supported_ecc, algo); else goto error; } } /* now check if the element is something like -ALGO */ else if (strncasecmp (&broken_list[i][1], "CTYPE-", 6) == 0) { if (strncasecmp (&broken_list[i][1], "CTYPE-ALL", 9) == 0) { bulk_fn(&(*priority_cache)-> cert_type, cert_type_priority_all); } else { if ((algo = gnutls_certificate_type_get_id (&broken_list[i][7])) != GNUTLS_CRT_UNKNOWN) fn(&(*priority_cache)-> cert_type, algo); else goto error; } } /* now check if the element is something like -ALGO */ else if (strncasecmp (&broken_list[i][1], "SIGN-", 5) == 0) { if (strncasecmp (&broken_list[i][1], "SIGN-ALL", 8) == 0) { bulk_fn(&(*priority_cache)-> sign_algo, sign_priority_default); } else { if ((algo = gnutls_sign_get_id (&broken_list[i][6])) != GNUTLS_SIGN_UNKNOWN) fn(&(*priority_cache)-> sign_algo, algo); else goto error; } } else if (strncasecmp (&broken_list[i][1], "MAC-ALL", 7) == 0) { bulk_fn(&(*priority_cache)->mac, mac_priority_normal); } else if (strncasecmp (&broken_list[i][1], "CIPHER-ALL", 10) == 0) { bulk_fn(&(*priority_cache)->cipher, cipher_priority_normal); } else if (strncasecmp (&broken_list[i][1], "KX-ALL", 6) == 0) { bulk_fn(&(*priority_cache)->kx, kx_priority_secure); } else goto error; } else if (broken_list[i][0] == '%') { if (strcasecmp(&broken_list[i][1], "COMPAT") == 0) { ENABLE_COMPAT((*priority_cache)); } else if (strcasecmp(&broken_list[i][1], "DUMBFW") == 0) { (*priority_cache)->dumbfw = 1; } else if (strcasecmp (&broken_list[i][1], "NO_EXTENSIONS") == 0) { (*priority_cache)->no_extensions = 1; } else if (strcasecmp (&broken_list[i][1], "STATELESS_COMPRESSION") == 0) { (*priority_cache)->stateless_compression = 1; } else if (strcasecmp (&broken_list[i][1], "VERIFY_ALLOW_SIGN_RSA_MD5") == 0) { prio_add(&(*priority_cache)->sign_algo, GNUTLS_SIGN_RSA_MD5); (*priority_cache)-> additional_verify_flags |= GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5; } else if (strcasecmp (&broken_list[i][1], "VERIFY_DISABLE_CRL_CHECKS") == 0) { (*priority_cache)-> additional_verify_flags |= GNUTLS_VERIFY_DISABLE_CRL_CHECKS; } else if (strcasecmp (&broken_list[i][1], "SSL3_RECORD_VERSION") == 0) (*priority_cache)->ssl3_record_version = 1; else if (strcasecmp(&broken_list[i][1], "LATEST_RECORD_VERSION") == 0) (*priority_cache)->ssl3_record_version = 0; else if (strcasecmp(&broken_list[i][1], "VERIFY_ALLOW_X509_V1_CA_CRT") == 0) (*priority_cache)-> additional_verify_flags |= GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT; else if (strcasecmp (&broken_list[i][1], "UNSAFE_RENEGOTIATION") == 0) { (*priority_cache)->sr = SR_UNSAFE; } else if (strcasecmp (&broken_list[i][1], "SAFE_RENEGOTIATION") == 0) { (*priority_cache)->sr = SR_SAFE; } else if (strcasecmp(&broken_list[i][1], "PARTIAL_RENEGOTIATION") == 0) { (*priority_cache)->sr = SR_PARTIAL; } else if (strcasecmp(&broken_list[i][1], "DISABLE_SAFE_RENEGOTIATION") == 0) { (*priority_cache)->sr = SR_DISABLED; } else if (strcasecmp(&broken_list[i][1], "SERVER_PRECEDENCE") == 0) { (*priority_cache)->server_precedence = 1; } else if (strcasecmp(&broken_list[i][1], "NEW_PADDING") == 0) { (*priority_cache)->new_record_padding = 1; } else goto error; } else goto error; } gnutls_free(darg); return 0; error: if (err_pos != NULL && i < broken_list_size) { *err_pos = priorities; for (j = 0; j < i; j++) { (*err_pos) += strlen(broken_list[j]) + 1; } } gnutls_free(darg); gnutls_free(*priority_cache); *priority_cache = NULL; return GNUTLS_E_INVALID_REQUEST; }
/* * In case of a server: if a NAME_DNS extension type is received then * it stores into the session the value of NAME_DNS. The server may * use gnutls_ext_get_server_name(), in order to access it. * * In case of a client: If a proper NAME_DNS extension type is found * in the session then it sends the extension to the peer. * */ static int _gnutls_server_name_recv_params(gnutls_session_t session, const uint8_t * data, size_t _data_size) { int i; const unsigned char *p; uint16_t len, type; ssize_t data_size = _data_size; int server_names = 0; server_name_ext_st *priv; extension_priv_data_t epriv; if (session->security_parameters.entity == GNUTLS_SERVER) { DECR_LENGTH_RET(data_size, 2, 0); len = _gnutls_read_uint16(data); if (len != data_size) { /* This is unexpected packet length, but * just ignore it, for now. */ gnutls_assert(); return 0; } p = data + 2; /* Count all server_names in the packet. */ while (data_size > 0) { DECR_LENGTH_RET(data_size, 1, 0); p++; DECR_LEN(data_size, 2); len = _gnutls_read_uint16(p); p += 2; if (len > 0) { DECR_LENGTH_RET(data_size, len, 0); server_names++; p += len; } else _gnutls_handshake_log ("HSK[%p]: Received (0) size server name (under attack?)\n", session); } /* we cannot accept more server names. */ if (server_names > MAX_SERVER_NAME_EXTENSIONS) { _gnutls_handshake_log ("HSK[%p]: Too many server names received (under attack?)\n", session); server_names = MAX_SERVER_NAME_EXTENSIONS; } if (server_names == 0) return 0; /* no names found */ priv = gnutls_calloc(1, sizeof(*priv)); if (priv == NULL) { gnutls_assert(); return GNUTLS_E_MEMORY_ERROR; } priv->server_names_size = server_names; p = data + 2; for (i = 0; i < server_names; i++) { type = *p; p++; len = _gnutls_read_uint16(p); p += 2; switch (type) { case 0: /* NAME_DNS */ if (len < MAX_SERVER_NAME_SIZE) { memcpy(priv->server_names[i].name, p, len); priv->server_names[i].name[len] = 0; priv->server_names[i].name_length = len; priv->server_names[i].type = GNUTLS_NAME_DNS; break; } } /* move to next record */ p += len; } epriv = priv; _gnutls_ext_set_session_data(session, GNUTLS_EXTENSION_SERVER_NAME, epriv); } return 0; }