gnutls_cert *apr_cert_list;
gnutls_privkey_t apr_pkey;
int apr_cert_list_length, size;
- gnutls_datum_t signature;
+ gnutls_datum_t signature = { NULL, 0 };
int total_data;
opaque *p;
gnutls_sign_algorithm_t sign_algo;
p = *data;
if (_gnutls_version_has_selectable_sighash (ver))
{
- sign_algorithm_st aid;
+ const sign_algorithm_st *aid;
/* error checking is not needed here since we have used those algorithms */
aid = _gnutls_sign_to_tls_aid (sign_algo);
- p[0] = aid.hash_algorithm;
- p[1] = aid.sign_algorithm;
+ if (aid == NULL)
+ {
+ ret = GNUTLS_E_UNKNOWN_ALGORITHM;
+ goto cleanup;
+ }
+
+ p[0] = aid->hash_algorithm;
+ p[1] = aid->sign_algorithm;
p += 2;
}
_gnutls_free_datum (&signature);
return total_data;
+
+cleanup:
+ _gnutls_free_datum (&signature);
+ gnutls_free(*data);
+ return ret;
}
int
gnutls_cert *apr_cert_list;
gnutls_privkey_t apr_pkey;
int apr_cert_list_length;
- gnutls_datum_t signature, ddata;
+ gnutls_datum_t signature = { NULL, 0 }, ddata;
gnutls_certificate_credentials_t cred;
gnutls_dh_params_t dh_params;
gnutls_sign_algorithm_t sign_algo;
&sign_algo)) < 0)
{
gnutls_assert ();
- gnutls_free (*data);
- return ret;
+ goto cleanup;
}
}
else
{
gnutls_assert ();
- return data_size; /* do not put a signature - ILLEGAL! */
+ ret = data_size; /* do not put a signature - ILLEGAL! */
+ goto cleanup;
}
*data = gnutls_realloc_fast (*data, data_size + signature.size + 4);
if (*data == NULL)
{
- _gnutls_free_datum (&signature);
gnutls_assert ();
- return GNUTLS_E_MEMORY_ERROR;
+ ret = GNUTLS_E_MEMORY_ERROR;
+ goto cleanup;
}
if (_gnutls_version_has_selectable_sighash (ver))
{
- sign_algorithm_st aid;
+ const sign_algorithm_st *aid;
if (sign_algo == GNUTLS_SIGN_UNKNOWN)
{
- _gnutls_free_datum (&signature);
- gnutls_assert ();
- return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
+ ret = GNUTLS_E_UNKNOWN_ALGORITHM;
+ goto cleanup;
}
aid = _gnutls_sign_to_tls_aid (sign_algo);
- (*data)[data_size++] = aid.hash_algorithm;
- (*data)[data_size++] = aid.sign_algorithm;
+ if (aid == NULL)
+ {
+ gnutls_assert();
+ ret = GNUTLS_E_UNKNOWN_ALGORITHM;
+ goto cleanup;
+ }
+
+ (*data)[data_size++] = aid->hash_algorithm;
+ (*data)[data_size++] = aid->sign_algorithm;
}
_gnutls_write_datum16 (&(*data)[data_size], signature);
_gnutls_free_datum (&signature);
return data_size;
+
+cleanup:
+ _gnutls_free_datum (&signature);
+ gnutls_free(*data);
+ return ret;
+
}
static int
_gnutls_sign_algorithm_write_params (gnutls_session_t session, opaque * data,
size_t max_data_size)
{
- opaque *p = data;
+ opaque *p = data, *len_p;
int len, i, j;
- sign_algorithm_st aid;
+ const sign_algorithm_st *aid;
- len = session->internals.priorities.sign_algo.algorithms * 2;
- if (max_data_size < len + 2)
+ if (max_data_size < (session->internals.priorities.sign_algo.algorithms*2) + 2)
{
gnutls_assert ();
return GNUTLS_E_SHORT_MEMORY_BUFFER;
}
- _gnutls_write_uint16 (len, p);
+ len = 0;
+ len_p = p;
+
p += 2;
- for (i = j = 0; i < len; i += 2, j++)
+ for (i = j = 0; i < session->internals.priorities.sign_algo.algorithms; i += 2, j++)
{
aid =
_gnutls_sign_to_tls_aid (session->internals.priorities.
sign_algo.priority[j]);
- *p = aid.hash_algorithm;
+
+ if (aid == NULL)
+ continue;
+
+ _gnutls_debug_log ("EXT[SIGA]: sent signature algo (%d.%d) %s\n", aid->hash_algorithm,
+ aid->sign_algorithm, gnutls_sign_get_name(session->internals.priorities.sign_algo.priority[j]));
+ *p = aid->hash_algorithm;
p++;
- *p = aid.sign_algorithm;
+ *p = aid->sign_algorithm;
p++;
-
+ len+=2;
}
+
+ _gnutls_write_uint16 (len, len_p);
+
return len + 2;
}
aid.sign_algorithm = data[i + 1];
sig = _gnutls_tls_aid_to_sign (&aid);
+
+ _gnutls_debug_log ("EXT[SIGA]: rcvd signature algo (%d.%d) %s\n", aid.hash_algorithm,
+ aid.sign_algorithm, gnutls_sign_get_name(sig));
+
if (sig != GNUTLS_SIGN_UNKNOWN)
{
priv->sign_algorithms[priv->sign_algorithms_size++] = sig;
gnutls_mac_algorithm_t mac;
/* See RFC 5246 HashAlgorithm and SignatureAlgorithm
for values to use in aid struct. */
- sign_algorithm_st aid;
+ const sign_algorithm_st aid;
};
typedef struct gnutls_sign_entry gnutls_sign_entry;
#define TLS_SIGN_AID_UNKNOWN {255, 255}
+static const sign_algorithm_st unknown_tls_aid = TLS_SIGN_AID_UNKNOWN;
static const gnutls_sign_entry sign_algorithms[] = {
{"RSA-SHA1", SIG_RSA_SHA1_OID, GNUTLS_SIGN_RSA_SHA1, GNUTLS_PK_RSA,
{
gnutls_sign_algorithm_t ret = GNUTLS_SIGN_UNKNOWN;
+ if (memcmp(aid, &unknown_tls_aid, sizeof(aid))==0)
+ return ret;
+
GNUTLS_SIGN_LOOP (if (p->aid.hash_algorithm == aid->hash_algorithm
&& p->aid.sign_algorithm == aid->sign_algorithm)
{
- ret = p->id; break;}
+ ret = p->id; break;
+ }
);
+
return ret;
}
-sign_algorithm_st
+/* Returns NULL if a valid AID is not found
+ */
+const sign_algorithm_st*
_gnutls_sign_to_tls_aid (gnutls_sign_algorithm_t sign)
{
- sign_algorithm_st ret = TLS_SIGN_AID_UNKNOWN;
+ const sign_algorithm_st * ret = NULL;
+
+ GNUTLS_SIGN_ALG_LOOP (ret = &p->aid);
- GNUTLS_SIGN_ALG_LOOP (ret = p->aid);
+ if (ret != NULL && memcmp(ret, &unknown_tls_aid, sizeof(*ret))==0)
+ return NULL;
return ret;
}
gnutls_mac_algorithm_t mac);
gnutls_sign_algorithm_t _gnutls_tls_aid_to_sign (const sign_algorithm_st *
aid);
-sign_algorithm_st _gnutls_sign_to_tls_aid (gnutls_sign_algorithm_t sign);
+const sign_algorithm_st* _gnutls_sign_to_tls_aid (gnutls_sign_algorithm_t sign);
gnutls_mac_algorithm_t
_gnutls_sign_get_hash_algorithm (gnutls_sign_algorithm_t);
gnutls_pk_algorithm_t _gnutls_sign_get_pk_algorithm (gnutls_sign_algorithm_t);