/** * gnutls_certificate_free_keys - Used to free all the keys from a gnutls_certificate_credentials_t structure * @sc: is an #gnutls_certificate_credentials_t structure. * * This function will delete all the keys and the certificates associated * with the given credentials. This function must not be called when a * TLS negotiation that uses the credentials is in progress. * **/ void gnutls_certificate_free_keys (gnutls_certificate_credentials_t sc) { unsigned i, j; for (i = 0; i < sc->ncerts; i++) { for (j = 0; j < sc->cert_list_length[i]; j++) { _gnutls_gcert_deinit (&sc->cert_list[i][j]); } gnutls_free (sc->cert_list[i]); } gnutls_free (sc->cert_list_length); sc->cert_list_length = NULL; gnutls_free (sc->cert_list); sc->cert_list = NULL; for (i = 0; i < sc->ncerts; i++) { _gnutls_gkey_deinit (&sc->pkey[i]); } gnutls_free (sc->pkey); sc->pkey = NULL; sc->ncerts = 0; }
/* if the peer's certificate is of 512 bits or less, returns non zero. */ int _gnutls_peers_cert_less_512 (gnutls_session_t session) { gnutls_cert peer_cert; int ret; cert_auth_info_t info = _gnutls_get_auth_info (session); if (info == NULL || info->ncerts == 0) { gnutls_assert (); /* we need this in order to get peer's certificate */ return 0; } if ((ret = _gnutls_get_auth_info_gcert (&peer_cert, session->security_parameters.cert_type, info, CERT_NO_COPY)) < 0) { gnutls_assert (); return 0; } if (peer_cert.subject_pk_algorithm != GNUTLS_PK_RSA) { gnutls_assert (); _gnutls_gcert_deinit (&peer_cert); return 0; } if (_gnutls_mpi_get_nbits (peer_cert.params[0]) <= 512) { _gnutls_gcert_deinit (&peer_cert); return 1; } _gnutls_gcert_deinit (&peer_cert); return 0; }
static int proc_dhe_server_kx (gnutls_session_t session, opaque * data, size_t _data_size) { int sigsize; opaque *sigdata; gnutls_datum_t vparams, signature; int ret; cert_auth_info_t info = _gnutls_get_auth_info (session); ssize_t data_size = _data_size; gnutls_cert peer_cert; gnutls_sign_algorithm_t sign_algo = GNUTLS_SIGN_UNKNOWN; gnutls_protocol_t ver = gnutls_protocol_get_version (session); if (info == NULL || info->ncerts == 0) { gnutls_assert (); /* we need this in order to get peer's certificate */ return GNUTLS_E_INTERNAL_ERROR; } ret = _gnutls_proc_dh_common_server_kx (session, data, _data_size, 0); if (ret < 0) { gnutls_assert (); return ret; } /* VERIFY SIGNATURE */ vparams.size = ret; vparams.data = data; sigdata = &data[vparams.size]; if (_gnutls_version_has_selectable_sighash (ver)) { sign_algorithm_st aid; DECR_LEN (data_size, 1); aid.hash_algorithm = *sigdata++; DECR_LEN (data_size, 1); aid.sign_algorithm = *sigdata++; sign_algo = _gnutls_tls_aid_to_sign (&aid); if (sign_algo == GNUTLS_SIGN_UNKNOWN) { gnutls_assert (); return GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM; } } DECR_LEN (data_size, 2); sigsize = _gnutls_read_uint16 (sigdata); sigdata += 2; DECR_LEN (data_size, sigsize); signature.data = sigdata; signature.size = sigsize; if ((ret = _gnutls_get_auth_info_gcert (&peer_cert, session->security_parameters.cert_type, info, CERT_NO_COPY)) < 0) { gnutls_assert (); return ret; } ret = _gnutls_handshake_verify_data (session, &peer_cert, &vparams, &signature, sign_algo); _gnutls_gcert_deinit (&peer_cert); if (ret < 0) { gnutls_assert (); return ret; } return ret; }
static int proc_srp_cert_server_kx (gnutls_session_t session, opaque * data, size_t _data_size) { ssize_t ret; int sigsize; gnutls_datum_t vparams, signature; ssize_t data_size; cert_auth_info_t info; gnutls_cert peer_cert; opaque *p; ret = _gnutls_proc_srp_server_kx (session, data, _data_size); if (ret < 0) return ret; data_size = _data_size - ret; info = _gnutls_get_auth_info (session); if (info == NULL || info->ncerts == 0) { gnutls_assert (); /* we need this in order to get peer's certificate */ return GNUTLS_E_INTERNAL_ERROR; } /* VERIFY SIGNATURE */ vparams.size = ret; /* all the data minus the signature */ vparams.data = data; p = &data[vparams.size]; DECR_LEN (data_size, 2); sigsize = _gnutls_read_uint16 (p); DECR_LEN (data_size, sigsize); signature.data = &p[2]; signature.size = sigsize; ret = _gnutls_get_auth_info_gcert (&peer_cert, session->security_parameters.cert_type, info, CERT_NO_COPY); if (ret < 0) { gnutls_assert (); return ret; } ret = _gnutls_handshake_verify_data (session, &peer_cert, &vparams, &signature, GNUTLS_SIGN_UNKNOWN); _gnutls_gcert_deinit (&peer_cert); if (ret < 0) { gnutls_assert (); return ret; } return 0; }
static int proc_rsa_export_server_kx (gnutls_session_t session, opaque * data, size_t _data_size) { uint16_t n_m, n_e; size_t _n_m, _n_e; uint8_t *data_m; uint8_t *data_e; int i, sigsize; gnutls_datum_t vparams, signature; int ret; ssize_t data_size = _data_size; cert_auth_info_t info; gnutls_cert peer_cert; info = _gnutls_get_auth_info (session); if (info == NULL || info->ncerts == 0) { gnutls_assert (); /* we need this in order to get peer's certificate */ return GNUTLS_E_INTERNAL_ERROR; } i = 0; DECR_LEN (data_size, 2); n_m = _gnutls_read_uint16 (&data[i]); i += 2; DECR_LEN (data_size, n_m); data_m = &data[i]; i += n_m; DECR_LEN (data_size, 2); n_e = _gnutls_read_uint16 (&data[i]); i += 2; DECR_LEN (data_size, n_e); data_e = &data[i]; i += n_e; _n_e = n_e; _n_m = n_m; if (_gnutls_mpi_scan_nz (&session->key->rsa[0], data_m, _n_m) != 0) { gnutls_assert (); return GNUTLS_E_MPI_SCAN_FAILED; } if (_gnutls_mpi_scan_nz (&session->key->rsa[1], data_e, _n_e) != 0) { gnutls_assert (); return GNUTLS_E_MPI_SCAN_FAILED; } _gnutls_rsa_export_set_pubkey (session, session->key->rsa[1], session->key->rsa[0]); /* VERIFY SIGNATURE */ vparams.size = n_m + n_e + 4; vparams.data = data; DECR_LEN (data_size, 2); sigsize = _gnutls_read_uint16 (&data[vparams.size]); DECR_LEN (data_size, sigsize); signature.data = &data[vparams.size + 2]; signature.size = sigsize; if ((ret = _gnutls_get_auth_info_gcert (&peer_cert, session->security_parameters.cert_type, info, CERT_NO_COPY)) < 0) { gnutls_assert (); return ret; } ret = _gnutls_verify_sig_params (session, &peer_cert, &vparams, &signature); _gnutls_gcert_deinit (&peer_cert); if (ret < 0) { gnutls_assert (); } return ret; }
/* This function reads the RSA parameters from peer's certificate; */ static int _gnutls_get_public_rsa_params (gnutls_session_t session, bigint_t params[MAX_PUBLIC_PARAMS_SIZE], int *params_len) { int ret; cert_auth_info_t info; gnutls_cert peer_cert; int i; /* normal non export case */ info = _gnutls_get_auth_info (session); if (info == NULL || info->ncerts == 0) { gnutls_assert (); return GNUTLS_E_INTERNAL_ERROR; } ret = _gnutls_get_auth_info_gcert (&peer_cert, session->security_parameters.cert_type, info, CERT_ONLY_PUBKEY | CERT_NO_COPY); if (ret < 0) { gnutls_assert (); return ret; } /* EXPORT case: */ if (_gnutls_cipher_suite_get_kx_algo (&session->security_parameters.current_cipher_suite) == GNUTLS_KX_RSA_EXPORT && _gnutls_mpi_get_nbits (peer_cert.params[0]) > 512) { _gnutls_gcert_deinit (&peer_cert); if (session->key->rsa[0] == NULL || session->key->rsa[1] == NULL) { gnutls_assert (); return GNUTLS_E_INTERNAL_ERROR; } if (*params_len < 2) { gnutls_assert (); return GNUTLS_E_INTERNAL_ERROR; } *params_len = 2; for (i = 0; i < *params_len; i++) { params[i] = _gnutls_mpi_copy (session->key->rsa[i]); } return 0; } /* end of export case */ if (*params_len < peer_cert.params_size) { gnutls_assert (); return GNUTLS_E_INTERNAL_ERROR; } *params_len = peer_cert.params_size; for (i = 0; i < *params_len; i++) { params[i] = _gnutls_mpi_copy (peer_cert.params[i]); } _gnutls_gcert_deinit (&peer_cert); return 0; }