/* Generate the signature. */
- /* If our certificate supports signing
- */
- if (apr_cert_list != NULL)
- if (apr_cert_list[0].keyUsage != 0)
- if (!
- (apr_cert_list[0].
- keyUsage & X509KEY_DIGITAL_SIGNATURE)) {
- gnutls_assert();
- gnutls_free( *data);
- return GNUTLS_E_X509_KEY_USAGE_VIOLATION;
- }
-
-
ddata.data = *data;
ddata.size = data_size;
if (apr_pkey != NULL) {
if ((ret =
_gnutls_generate_sig_params(
- state, apr_pkey, &ddata, &signature)) < 0) {
+ state, &apr_cert_list[0], apr_pkey, &ddata, &signature)) < 0) {
gnutls_assert();
gnutls_free( *data);
return ret;
signature.data = &data[vparams.size+2];
signature.size = GMIN(data_size-vparams.size-2, sigsize);
- if (state->gnutls_internals.peer_cert.version == 0) { /* this is the only way to check
- * if it is initialized
- */
- gnutls_assert();
- return GNUTLS_E_X509_CERTIFICATE_ERROR;
- }
ret = _gnutls_verify_sig_params( state, &state->gnutls_internals.peer_cert, &vparams, &signature);
if (ret<0) {
gnutls_assert();
return pdatasize;
}
+
#define CLEAR_CERTS for(x=0;x<peer_certificate_list_size;x++) gnutls_free_cert(peer_certificate_list[x])
int _gnutls_proc_x509_server_certificate(GNUTLS_STATE state, opaque * data, int data_size)
{
_gnutls_copy_x509_client_auth_info(info, &peer_certificate_list[0], verify);
- /* This works for the client
- */
- if ( peer_certificate_list[0].keyUsage != 0)
- if ( !(peer_certificate_list[0].keyUsage & X509KEY_KEY_ENCIPHERMENT)) {
- gnutls_assert();
- CLEAR_CERTS;
- gnutls_free(peer_certificate_list);
- return GNUTLS_E_X509_KEY_USAGE_VIOLATION;
- }
+ if ( (ret=_gnutls_check_x509_key_usage( &peer_certificate_list[0], gnutls_get_current_kx( state))) < 0) {
+ gnutls_assert();
+ CLEAR_CERTS;
+ gnutls_free(peer_certificate_list);
+ return ret;
+ }
CLEAR_CERTS;
gnutls_free(peer_certificate_list);
}
+#ifdef DEBUG
+# warning CHECK FOR DSS
+#endif
+
#define RSA_SIGN 1
+int _gnutls_check_supported_sign_algo( uint8 algo) {
+ switch(algo) {
+ case RSA_SIGN:
+ return 0;
+ }
+
+ return -1;
+}
+
int _gnutls_proc_x509_cert_req(GNUTLS_STATE state, opaque * data, int data_size)
{
int size, ret;
found = 0;
for (i = 0; i < size; i++, p++) {
DECR_LEN(dsize, 1);
- if (*p == RSA_SIGN)
+ if ( _gnutls_check_supported_sign_algo(*p)==0)
found = 1;
}
return ret;
}
- /* If our certificate supports signing
- */
- if ( apr_cert_list != NULL)
- if ( apr_cert_list[0].keyUsage != 0)
- if ( !(apr_cert_list[0].keyUsage & X509KEY_DIGITAL_SIGNATURE)) {
- gnutls_assert();
- return GNUTLS_E_X509_KEY_USAGE_VIOLATION;
- }
-
if (apr_pkey != NULL) {
- if ( (ret=_gnutls_generate_sig_from_hdata( state, apr_pkey, &signature)) < 0) {
+ if ( (ret=_gnutls_generate_sig_from_hdata( state, &apr_cert_list[0], apr_pkey, &signature)) < 0) {
gnutls_assert();
return ret;
}
sig.data = pdata;
sig.size = size;
-
+
if ( (ret=_gnutls_verify_sig_hdata( state, &state->gnutls_internals.peer_cert, &sig, data_size+HANDSHAKE_HEADER_SIZE))<0) {
gnutls_assert();
return ret;
int gnutls_set_db_name( GNUTLS_STATE state, char* filename);
int gnutls_clean_db( GNUTLS_STATE state);
+void gnutls_set_max_handshake_data_buffer_size( GNUTLS_STATE state, int max);
+
/* returns libgnutls version */
const char* gnutls_check_version();
old_buffer = state->gnutls_internals.hash_buffer.size;
state->gnutls_internals.hash_buffer.size += length;
+ if (state->gnutls_internals.max_handshake_data_buffer_size > 0 && state->gnutls_internals.hash_buffer.size > state->gnutls_internals.max_handshake_data_buffer_size) {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+
#ifdef BUFFERS_DEBUG
_gnutls_log( "HASH BUFFER: Inserted %d bytes of Data\n", length);
#endif
}
/* Returns 0 if it's ok to use the KXAlgorithm with this cert
- * (using KeyUsage field). 1 otherwise.
+ * (using KeyUsage field).
*/
-static int _gnutls_check_x509_key_usage(gnutls_cert * cert,
+int _gnutls_check_x509_key_usage(gnutls_cert * cert,
KXAlgorithm alg)
{
if (_gnutls_map_kx_get_cred(alg) == GNUTLS_X509PKI) {
if (!
(cert->
keyUsage & X509KEY_KEY_ENCIPHERMENT))
- return 1;
+ return GNUTLS_E_X509_KEY_USAGE_VIOLATION;
else
return 0;
}
if (!
(cert->
keyUsage & X509KEY_DIGITAL_SIGNATURE))
- return 1;
+ return GNUTLS_E_X509_KEY_USAGE_VIOLATION;
else
return 0;
}
return 0;
default:
- return 1;
+ gnutls_assert();
+ return GNUTLS_E_X509_KEY_USAGE_VIOLATION;
}
}
return 0;
void _gnutls_int2str(int k, char* data);
int _gnutls_get_name_type( node_asn *rasn, char *root, gnutls_DN * dn);
void gnutls_free_cert(gnutls_cert cert);
+int _gnutls_check_x509_key_usage(gnutls_cert * cert, KXAlgorithm alg);
#endif
return ret;
}
+
+/**
+ * gnutls_set_max_handshake_data_buffer_size - This function will set the maximum size of handshake message sequence
+ * @state: is a a &GNUTLS_STATE structure.
+ * @max: is the maximum number.
+ *
+ * This function will set the maximum size of the handshake message sequence.
+ * Since the handshake messages are kept into memory until the handshake is successful
+ * this function allows you to set the maximum number of bytes that will be kept.
+ * The default value is 128kb which is large enough. Set this to 0 if you do not want
+ * to set an upper limit.
+ *
+ **/
+void gnutls_set_max_handshake_data_buffer_size( GNUTLS_STATE state, int max) {
+ state->gnutls_internals.max_handshake_data_buffer_size = max;
+}
void _gnutls_set_client_random( GNUTLS_STATE state, uint8* random);
int _gnutls_create_random( opaque* dst);
int _gnutls_remove_unwanted_ciphersuites( GNUTLS_STATE state, GNUTLS_CipherSuite ** cipherSuites, int numCipherSuites);
+void gnutls_set_max_handshake_data_buffer_size( GNUTLS_STATE state, int max);
#define set_adv_version( state, major, minor) \
state->gnutls_internals.adv_version_major = data[pos]; \
#define MAX24 16777215
#define MAX16 65535
+/* The sequence of handshake messages should not
+ * be larger than this value.
+ */
+#define MAX_HANDSHAKE_DATA_BUFFER_SIZE 128*1024
+
#define TLS_RANDOM_SIZE 32
#define TLS_MAX_SESSION_ID_SIZE 32
#define TLS_MASTER_SIZE 48
*/
int (*x509_client_cert_callback)(void*,void*,int, void*, int);
gnutls_cert peer_cert;
+ int max_handshake_data_buffer_size;
} GNUTLS_INTERNALS;
struct GNUTLS_STATE_INT {
gnutls_set_lowat((*state), DEFAULT_LOWAT); /* the default for tcp */
+ gnutls_set_max_handshake_data_buffer_size( (*state), MAX_HANDSHAKE_DATA_BUFFER_SIZE);
+
/* everything else not initialized here is initialized
* as NULL or 0. This is why calloc is used.
*/
/* Generates a signature of all the previous sended packets in the
* handshake procedure.
*/
-int _gnutls_generate_sig_from_hdata( GNUTLS_STATE state, gnutls_private_key *pkey, gnutls_datum *signature) {
+int _gnutls_generate_sig_from_hdata( GNUTLS_STATE state, gnutls_cert* cert, gnutls_private_key *pkey, gnutls_datum *signature) {
gnutls_datum data;
int size = gnutls_getHashDataBufferSize( state);
int ret;
gnutls_readHashDataFromBuffer( state, data.data, data.size);
- ret = _gnutls_pkcs1_rsa_generate_sig( pkey, &data, signature);
+ ret = _gnutls_pkcs1_rsa_generate_sig( cert, pkey, &data, signature);
gnutls_free_datum( &data);
if (ret < 0) {
gnutls_assert();
/* Generates a signature of all the random data and the parameters.
* Used in DHE_* ciphersuites.
*/
-int _gnutls_generate_sig_params( GNUTLS_STATE state, gnutls_private_key *pkey, gnutls_datum* params, gnutls_datum *signature)
+int _gnutls_generate_sig_params( GNUTLS_STATE state, gnutls_cert* cert, gnutls_private_key *pkey, gnutls_datum* params, gnutls_datum *signature)
{
gnutls_datum sdata;
int size = 2*TLS_RANDOM_SIZE;
memcpy( &sdata.data[TLS_RANDOM_SIZE], state->security_parameters.server_random, TLS_RANDOM_SIZE);
memcpy( &sdata.data[2*TLS_RANDOM_SIZE], params->data, params->size);
- ret = _gnutls_pkcs1_rsa_generate_sig( pkey, &sdata, signature);
+ ret = _gnutls_pkcs1_rsa_generate_sig( cert, pkey, &sdata, signature);
gnutls_free_datum( &sdata);
if (ret < 0) {
/* This will create a PKCS1 signature, as defined in the TLS protocol.
+ * Cert is the certificate of the corresponding private key. It is only checked if
+ * it supports signing.
*/
-int _gnutls_pkcs1_rsa_generate_sig( gnutls_private_key *pkey, const gnutls_datum *data, gnutls_datum *signature)
+int _gnutls_pkcs1_rsa_generate_sig( gnutls_cert* cert, gnutls_private_key *pkey, const gnutls_datum *data, gnutls_datum *signature)
{
int ret;
opaque digest[20+16];
gnutls_datum tmpdata;
GNUTLS_HASH_HANDLE td;
+ /* If our certificate supports signing
+ */
+
+ if ( cert != NULL)
+ if ( cert->keyUsage != 0)
+ if ( !(cert->keyUsage & X509KEY_DIGITAL_SIGNATURE)) {
+ gnutls_assert();
+ return GNUTLS_E_X509_KEY_USAGE_VIOLATION;
+ }
+
switch(pkey->pk_algorithm) {
case GNUTLS_PK_RSA:
opaque digest[20+16];
GNUTLS_HASH_HANDLE td;
+ if (cert->version == 0 || cert==NULL) { /* this is the only way to check
+ * if it is initialized
+ */
+ gnutls_assert();
+ return GNUTLS_E_X509_CERTIFICATE_ERROR;
+ }
+
+ /* If the certificate supports signing continue.
+ */
+ if ( cert != NULL)
+ if ( cert->keyUsage != 0)
+ if ( !(cert->keyUsage & X509KEY_DIGITAL_SIGNATURE)) {
+ gnutls_assert();
+ return GNUTLS_E_X509_KEY_USAGE_VIOLATION;
+ }
+
switch(cert->subject_pk_algorithm) {
case GNUTLS_PK_RSA:
# include <auth_x509.h>
CertificateStatus gnutls_x509_verify_signature(gnutls_cert* cert, gnutls_cert* issuer);
-int _gnutls_pkcs1_rsa_generate_sig( gnutls_private_key *pkey, const gnutls_datum *data, gnutls_datum *signature);
-int _gnutls_generate_sig_from_hdata( GNUTLS_STATE state, gnutls_private_key *pkey, gnutls_datum *signature);
-int _gnutls_generate_sig_params( GNUTLS_STATE state, gnutls_private_key *pkey, gnutls_datum* params, gnutls_datum *signature);
+int _gnutls_pkcs1_rsa_generate_sig( gnutls_cert*, gnutls_private_key *pkey, const gnutls_datum *data, gnutls_datum *signature);
+int _gnutls_generate_sig_from_hdata( GNUTLS_STATE state, gnutls_cert* cert, gnutls_private_key *pkey, gnutls_datum *signature);
+int _gnutls_generate_sig_params( GNUTLS_STATE state, gnutls_cert* cert, gnutls_private_key *pkey, gnutls_datum* params, gnutls_datum *signature);
int _gnutls_verify_sig_hdata( GNUTLS_STATE state, gnutls_cert *cert, gnutls_datum* signature, int ubuffer_size);
int _gnutls_verify_sig_params( GNUTLS_STATE state, gnutls_cert *cert, const gnutls_datum* params, gnutls_datum* signature);