/* Sets the current connection session to conform with the * Security parameters(pending session), and initializes encryption. * Actually it initializes and starts encryption ( so it needs * secrets and random numbers to have been negotiated) * This is to be called after sending the Change Cipher Spec packet. */ int _gnutls_connection_state_init(gnutls_session_t session) { int ret; /* Setup the master secret */ if ((ret = _gnutls_generate_master(session, 0)) < 0) return gnutls_assert_val(ret); return 0; }
/* Generates a signature of all the previous sent packets in the * handshake procedure. (20040227: now it works for SSL 3.0 as well) */ int _gnutls_tls_sign_hdata (gnutls_session_t session, gnutls_cert * cert, gnutls_privkey * pkey, gnutls_datum_t * signature) { gnutls_datum_t dconcat; int ret; opaque concat[36]; digest_hd_st td_md5; digest_hd_st td_sha; gnutls_protocol_t ver = gnutls_protocol_get_version (session); ret = _gnutls_hash_copy (&td_sha, &session->internals.handshake_mac_handle_sha); if (ret < 0) { gnutls_assert (); return ret; } if (ver == GNUTLS_SSL3) { ret = _gnutls_generate_master (session, 1); if (ret < 0) { gnutls_assert (); return ret; } _gnutls_mac_deinit_ssl3_handshake (&td_sha, &concat[16], session->security_parameters. master_secret, GNUTLS_MASTER_SIZE); } else _gnutls_hash_deinit (&td_sha, &concat[16]); switch (cert->subject_pk_algorithm) { case GNUTLS_PK_RSA: ret = _gnutls_hash_copy (&td_md5, &session->internals.handshake_mac_handle_md5); if (ret < 0) { gnutls_assert (); return ret; } if (ver == GNUTLS_SSL3) _gnutls_mac_deinit_ssl3_handshake (&td_md5, concat, session->security_parameters. master_secret, GNUTLS_MASTER_SIZE); else _gnutls_hash_deinit (&td_md5, concat); dconcat.data = concat; dconcat.size = 36; break; case GNUTLS_PK_DSA: dconcat.data = &concat[16]; dconcat.size = 20; break; default: gnutls_assert (); return GNUTLS_E_INTERNAL_ERROR; } ret = _gnutls_tls_sign (session, cert, pkey, &dconcat, signature); if (ret < 0) { gnutls_assert (); } return ret; }
/* Verifies a TLS signature (like the one in the client certificate * verify message). */ int _gnutls_verify_sig_hdata (gnutls_session_t session, gnutls_cert * cert, gnutls_datum_t * signature) { int ret; opaque concat[36]; digest_hd_st td_md5; digest_hd_st td_sha; gnutls_datum_t dconcat; gnutls_protocol_t ver = gnutls_protocol_get_version (session); ret = _gnutls_hash_copy (&td_md5, &session->internals.handshake_mac_handle_md5); if (ret < 0) { gnutls_assert (); return ret; } ret = _gnutls_hash_copy (&td_sha, &session->internals.handshake_mac_handle_sha); if (ret < 0) { gnutls_assert (); _gnutls_hash_deinit (&td_md5, NULL); return GNUTLS_E_HASH_FAILED; } if (ver == GNUTLS_SSL3) { ret = _gnutls_generate_master (session, 1); if (ret < 0) { gnutls_assert (); return ret; } _gnutls_mac_deinit_ssl3_handshake (&td_md5, concat, session->security_parameters. master_secret, GNUTLS_MASTER_SIZE); _gnutls_mac_deinit_ssl3_handshake (&td_sha, &concat[16], session->security_parameters. master_secret, GNUTLS_MASTER_SIZE); } else { _gnutls_hash_deinit (&td_md5, concat); _gnutls_hash_deinit (&td_sha, &concat[16]); } dconcat.data = concat; dconcat.size = 20 + 16; /* md5+ sha */ ret = _gnutls_verify_sig (cert, &dconcat, signature, 16); if (ret < 0) { gnutls_assert (); return ret; } return ret; }
/* Generates a signature of all the previous sent packets in the * handshake procedure. * 20040227: now it works for SSL 3.0 as well * 20091031: works for TLS 1.2 too! * * For TLS1.x, x<2 returns negative for failure and zero or unspecified for success. * For TLS1.2 returns the signature algorithm used on success, or a negative error code; */ int _gnutls_handshake_sign_crt_vrfy(gnutls_session_t session, gnutls_pcert_st * cert, gnutls_privkey_t pkey, gnutls_datum_t * signature) { gnutls_datum_t dconcat; int ret; uint8_t concat[MAX_SIG_SIZE]; digest_hd_st td_md5; digest_hd_st td_sha; const version_entry_st *ver = get_version(session); gnutls_pk_algorithm_t pk = gnutls_privkey_get_pk_algorithm(pkey, NULL); if (unlikely(ver == NULL)) return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); if (_gnutls_version_has_selectable_sighash(ver)) return _gnutls_handshake_sign_crt_vrfy12(session, cert, pkey, signature); ret = _gnutls_hash_init(&td_sha, hash_to_entry(GNUTLS_DIG_SHA1)); if (ret < 0) { gnutls_assert(); return ret; } _gnutls_hash(&td_sha, session->internals.handshake_hash_buffer.data, session->internals.handshake_hash_buffer.length); if (ver->id == GNUTLS_SSL3) { ret = _gnutls_generate_master(session, 1); if (ret < 0) { gnutls_assert(); _gnutls_hash_deinit(&td_sha, NULL); return ret; } ret = _gnutls_mac_deinit_ssl3_handshake(&td_sha, &concat[16], session->security_parameters. master_secret, GNUTLS_MASTER_SIZE); if (ret < 0) return gnutls_assert_val(ret); } else _gnutls_hash_deinit(&td_sha, &concat[16]); /* ensure 1024 bit DSA keys are used */ ret = _gnutls_pubkey_compatible_with_sig(session, cert->pubkey, ver, GNUTLS_SIGN_UNKNOWN); if (ret < 0) return gnutls_assert_val(ret); switch (pk) { case GNUTLS_PK_RSA: ret = _gnutls_hash_init(&td_md5, hash_to_entry(GNUTLS_DIG_MD5)); if (ret < 0) return gnutls_assert_val(ret); _gnutls_hash(&td_md5, session->internals.handshake_hash_buffer.data, session->internals.handshake_hash_buffer. length); if (ver->id == GNUTLS_SSL3) { ret = _gnutls_mac_deinit_ssl3_handshake(&td_md5, concat, session->security_parameters. master_secret, GNUTLS_MASTER_SIZE); if (ret < 0) return gnutls_assert_val(ret); } else _gnutls_hash_deinit(&td_md5, concat); dconcat.data = concat; dconcat.size = 36; break; case GNUTLS_PK_DSA: case GNUTLS_PK_EC: dconcat.data = &concat[16]; dconcat.size = 20; break; default: return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); } ret = sign_tls_hash(session, NULL, cert, pkey, &dconcat, signature); if (ret < 0) { gnutls_assert(); } return ret; }
/* Verifies a TLS signature (like the one in the client certificate * verify message). */ int _gnutls_handshake_verify_crt_vrfy(gnutls_session_t session, gnutls_pcert_st * cert, gnutls_datum_t * signature, gnutls_sign_algorithm_t sign_algo) { int ret; uint8_t concat[MAX_SIG_SIZE]; digest_hd_st td_md5; digest_hd_st td_sha; gnutls_datum_t dconcat; const version_entry_st *ver = get_version(session); _gnutls_handshake_log("HSK[%p]: verify cert vrfy: using %s\n", session, gnutls_sign_algorithm_get_name(sign_algo)); if (unlikely(ver == NULL)) return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); if (_gnutls_version_has_selectable_sighash(ver)) return _gnutls_handshake_verify_crt_vrfy12(session, cert, signature, sign_algo); ret = _gnutls_hash_init(&td_md5, hash_to_entry(GNUTLS_DIG_MD5)); if (ret < 0) { gnutls_assert(); return ret; } ret = _gnutls_hash_init(&td_sha, hash_to_entry(GNUTLS_DIG_SHA1)); if (ret < 0) { gnutls_assert(); _gnutls_hash_deinit(&td_md5, NULL); return GNUTLS_E_HASH_FAILED; } _gnutls_hash(&td_sha, session->internals.handshake_hash_buffer.data, session->internals.handshake_hash_buffer_prev_len); _gnutls_hash(&td_md5, session->internals.handshake_hash_buffer.data, session->internals.handshake_hash_buffer_prev_len); if (ver->id == GNUTLS_SSL3) { ret = _gnutls_generate_master(session, 1); if (ret < 0) { _gnutls_hash_deinit(&td_md5, NULL); _gnutls_hash_deinit(&td_sha, NULL); return gnutls_assert_val(ret); } ret = _gnutls_mac_deinit_ssl3_handshake(&td_md5, concat, session->security_parameters. master_secret, GNUTLS_MASTER_SIZE); if (ret < 0) { _gnutls_hash_deinit(&td_sha, NULL); return gnutls_assert_val(ret); } ret = _gnutls_mac_deinit_ssl3_handshake(&td_sha, &concat[16], session->security_parameters. master_secret, GNUTLS_MASTER_SIZE); if (ret < 0) { return gnutls_assert_val(ret); } } else { _gnutls_hash_deinit(&td_md5, concat); _gnutls_hash_deinit(&td_sha, &concat[16]); } dconcat.data = concat; dconcat.size = 20 + 16; /* md5+ sha */ ret = verify_tls_hash(session, ver, cert, &dconcat, signature, 16, GNUTLS_SIGN_UNKNOWN, gnutls_pubkey_get_pk_algorithm(cert->pubkey, NULL)); if (ret < 0) { gnutls_assert(); return ret; } return ret; }
/* Verifies a TLS signature (like the one in the client certificate * verify message). */ int _gnutls_handshake_verify_cert_vrfy (gnutls_session_t session, gnutls_cert * cert, gnutls_datum_t * signature, gnutls_sign_algorithm_t sign_algo) { int ret; opaque concat[MAX_SIG_SIZE]; digest_hd_st td_md5; digest_hd_st td_sha; gnutls_datum_t dconcat; gnutls_protocol_t ver = gnutls_protocol_get_version (session); if (session->security_parameters.handshake_mac_handle_type == HANDSHAKE_MAC_TYPE_12) { return _gnutls_handshake_verify_cert_vrfy12 (session, cert, signature, sign_algo); } else if (session->security_parameters.handshake_mac_handle_type != HANDSHAKE_MAC_TYPE_10) { gnutls_assert (); return GNUTLS_E_INTERNAL_ERROR; } ret = _gnutls_hash_copy (&td_md5, &session->internals.handshake_mac_handle.tls10.md5); if (ret < 0) { gnutls_assert (); return ret; } ret = _gnutls_hash_copy (&td_sha, &session->internals.handshake_mac_handle.tls10.sha); if (ret < 0) { gnutls_assert (); _gnutls_hash_deinit (&td_md5, NULL); return GNUTLS_E_HASH_FAILED; } if (ver == GNUTLS_SSL3) { ret = _gnutls_generate_master (session, 1); if (ret < 0) { gnutls_assert (); return ret; } _gnutls_mac_deinit_ssl3_handshake (&td_md5, concat, session-> security_parameters.master_secret, GNUTLS_MASTER_SIZE); _gnutls_mac_deinit_ssl3_handshake (&td_sha, &concat[16], session-> security_parameters.master_secret, GNUTLS_MASTER_SIZE); } else { _gnutls_hash_deinit (&td_md5, concat); _gnutls_hash_deinit (&td_sha, &concat[16]); } dconcat.data = concat; dconcat.size = 20 + 16; /* md5+ sha */ ret = _gnutls_verify_sig (cert, &dconcat, signature, 16, cert->subject_pk_algorithm); if (ret < 0) { gnutls_assert (); return ret; } return ret; }
/* Generates a signature of all the previous sent packets in the * handshake procedure. * 20040227: now it works for SSL 3.0 as well * 20091031: works for TLS 1.2 too! * * For TLS1.x, x<2 returns negative for failure and zero or unspecified for success. * For TLS1.2 returns the signature algorithm used on success, or a negative value; */ int _gnutls_handshake_sign_cert_vrfy (gnutls_session_t session, gnutls_pcert_st* cert, gnutls_privkey_t pkey, gnutls_datum_t * signature) { gnutls_datum_t dconcat; int ret; opaque concat[MAX_SIG_SIZE]; digest_hd_st td_md5; digest_hd_st td_sha; gnutls_protocol_t ver = gnutls_protocol_get_version (session); gnutls_pk_algorithm_t pk = gnutls_pubkey_get_pk_algorithm(cert->pubkey, NULL); if (session->security_parameters.handshake_mac_handle_type == HANDSHAKE_MAC_TYPE_12) { return _gnutls_handshake_sign_cert_vrfy12 (session, cert, pkey, signature); } else if (session->security_parameters.handshake_mac_handle_type != HANDSHAKE_MAC_TYPE_10) { gnutls_assert (); return GNUTLS_E_INTERNAL_ERROR; } ret = _gnutls_hash_copy (&td_sha, &session->internals.handshake_mac_handle.tls10.sha); if (ret < 0) { gnutls_assert (); return ret; } if (ver == GNUTLS_SSL3) { ret = _gnutls_generate_master (session, 1); if (ret < 0) { gnutls_assert (); _gnutls_hash_deinit (&td_sha, NULL); return ret; } ret = _gnutls_mac_deinit_ssl3_handshake (&td_sha, &concat[16], session-> security_parameters.master_secret, GNUTLS_MASTER_SIZE); if (ret < 0) return gnutls_assert_val(ret); } else _gnutls_hash_deinit (&td_sha, &concat[16]); /* ensure 1024 bit DSA keys are used */ ret = _gnutls_pubkey_compatible_with_sig(cert->pubkey, ver, GNUTLS_SIGN_UNKNOWN); if (ret < 0) return gnutls_assert_val(ret); switch (pk) { case GNUTLS_PK_RSA: ret = _gnutls_hash_copy (&td_md5, &session->internals.handshake_mac_handle.tls10. md5); if (ret < 0) { gnutls_assert (); return ret; } if (ver == GNUTLS_SSL3) { ret = _gnutls_mac_deinit_ssl3_handshake (&td_md5, concat, session-> security_parameters.master_secret, GNUTLS_MASTER_SIZE); if (ret < 0) return gnutls_assert_val(ret); } else _gnutls_hash_deinit (&td_md5, concat); dconcat.data = concat; dconcat.size = 36; break; case GNUTLS_PK_DSA: dconcat.data = &concat[16]; dconcat.size = 20; break; default: return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); } ret = sign_tls_hash (session, GNUTLS_DIG_NULL, cert, pkey, &dconcat, signature); if (ret < 0) { gnutls_assert (); } return ret; }