#include "gnutls_datum.h"
#include "auth_x509.h"
+#if 0
int gen_rsa_server_kx(GNUTLS_KEY, opaque **);
+#endif
+int gen_rsa_certificate(GNUTLS_KEY, opaque **);
+int proc_rsa_client_kx( GNUTLS_KEY, opaque*, int);
MOD_AUTH_STRUCT rsa_auth_struct = {
"RSA",
- gen_rsa_server_kx,
- NULL,
+ gen_rsa_certificate,
+/* not needed!!! gen_rsa_server_kx, */ NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
+ proc_rsa_client_kx,
NULL,
NULL
};
}
-#define dat_set( d,s,len) d.data=gnutls_malloc(len); \
- if (d.data==NULL) return GNUTLS_E_MEMORY_ERROR; \
- memcpy(d.data, s, len); d.size = len;
-
/* This function reads the RSA parameters from the given(?) certificate.
*/
static int _gnutls_get_rsa_params( GNUTLS_KEY key, RSA_Params * params, gnutls_datum cert)
return GNUTLS_E_PARSING_ERROR;
}
- if (!strcmp(str, "111")) { /* pkix-1 1 - RSA */
+ if (!strcmp(str, "1 2 840 113549 1 1 1")) { /* pkix-1 1 - RSA */
len = sizeof(str);
result =
read_value("certificate2.tbsCertificate.subjectPublicKeyInfo.parameters", str, &len);
delete_structure("rsapublickey");
return GNUTLS_E_MPI_SCAN_FAILED;
}
- dat_set(params->rsa_modulus, str, len);
+ if (gnutls_set_datum(¶ms->rsa_modulus, str, len) < 0) {
+ gnutls_assert();
+ delete_structure("rsapublickey");
+ return GNUTLS_E_MEMORY_ERROR;
+ }
len = sizeof(str);
result =
if (result != ASN_OK) {
gnutls_assert();
delete_structure("rsapublickey");
- gnutls_free(params->rsa_modulus.data);
+ gnutls_free_datum(¶ms->rsa_modulus);
gcry_mpi_release(key->A);
return GNUTLS_E_PARSING_ERROR;
}
GCRYMPI_FMT_USG, str, &len) != 0) {
gnutls_assert();
gcry_mpi_release(key->A);
- gnutls_free(params->rsa_modulus.data);
+ gnutls_free_datum(¶ms->rsa_modulus);
delete_structure("rsapublickey");
return GNUTLS_E_MPI_SCAN_FAILED;
}
- dat_set(params->rsa_exponent, str, len);
+ if (gnutls_set_datum(¶ms->rsa_exponent, str, len) < 0) {
+ gcry_mpi_release(key->A);
+ gnutls_free_datum(¶ms->rsa_modulus);
+ delete_structure("rsapublickey");
+ return GNUTLS_E_MEMORY_ERROR;
+ }
delete_structure("rsapublickey");
return ret;
}
+/* This function reads the RSA parameters from the given private key
+ * cert is not a certificate but a der structure containing the private
+ * key(s).
+ */
+static int _gnutls_get_private_rsa_params( GNUTLS_KEY key, gnutls_datum cert)
+{
+ int ret = 0, result;
+ opaque str[5*1024];
+ int len = sizeof(str);
+
+ create_structure("rsa_key", "PKCS-1");
+
+ result = get_der("rsa_key", cert.data, cert.size);
+ if (result != ASN_OK) {
+ gnutls_assert();
+ return GNUTLS_E_PARSING_ERROR;
+ }
+
+ result =
+ read_value("rsa_key.RSAPrivateKey.privateExponent", str, &len);
+ if (result != ASN_OK) {
+ gnutls_assert();
+ delete_structure("rsa_key");
+ return GNUTLS_E_PARSING_ERROR;
+ }
+ if (gcry_mpi_scan(&key->u,
+ GCRYMPI_FMT_USG, str, &len) != 0) {
+ gnutls_assert();
+ delete_structure("rsa_key");
+ return GNUTLS_E_MPI_SCAN_FAILED;
+ }
+
+
+ len = sizeof(str);
+ result =
+ read_value("rsa_key.modulus", str, &len);
+ if (result != ASN_OK) {
+ gnutls_assert();
+ delete_structure("rsa_key");
+ gcry_mpi_release(key->u);
+ return GNUTLS_E_PARSING_ERROR;
+ }
+
+ if (gcry_mpi_scan(&key->A,
+ GCRYMPI_FMT_USG, str, &len) != 0) {
+ gnutls_assert();
+ delete_structure("rsa_key");
+ gcry_mpi_release(key->u);
+ return GNUTLS_E_MPI_SCAN_FAILED;
+ }
+
+ delete_structure("rsa_key");
+
+ return ret;
+}
+
+#if 0 /* wow ... this was not needed ! */
int gen_rsa_server_kx(GNUTLS_KEY key, opaque ** data)
{
RSA_Params params;
}
ret =
- _gnutls_get_rsa_params(key, ¶ms, cred->cert_list[0]);
+ _gnutls_get_rsa_params(key, ¶ms, cred->pkey);
if (ret < 0) {
gnutls_assert();
WRITEdatum16(pdata, params.rsa_exponent);
pdata += params.rsa_exponent.size;
+ gnutls_free_datum(¶ms.rsa_modulus);
+ gnutls_free_datum(¶ms.rsa_modulus);
+
ret = _gnutls_calc_rsa_signature( key, (*data), ret-20-16, pdata);
if (ret< 0) {
gnutls_free((*data));
return ret;
}
+#endif
+
+int gen_rsa_certificate(GNUTLS_KEY key, opaque ** data)
+{
+ RSA_Params params;
+ const X509PKI_SERVER_CREDENTIALS *cred;
+ int ret, i;
+ opaque* pdata;
+
+ cred = _gnutls_get_cred(key, GNUTLS_X509PKI, NULL);
+ if (cred == NULL) {
+ gnutls_assert();
+ return GNUTLS_E_INSUFICIENT_CRED;
+ }
+
+ ret = 3;
+ for (i=0;i<cred->cert_list_size;i++) {
+ ret += cred->cert_list[i].size + 3;
+ /* hold size
+ * for uint24 */
+ }
+
+ (*data) = gnutls_malloc(ret);
+ pdata = (*data);
+
+ if (pdata == NULL) {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+
+ WRITEuint24( ret-3, pdata);
+ pdata+=3;
+ for (i=0;i<cred->cert_list_size;i++) {
+ WRITEdatum24( pdata, cred->cert_list[i]);
+ pdata += 3 + cred->cert_list[i].size;
+ }
+
+ return ret;
+}
+
+
+int proc_anon_client_kx( GNUTLS_KEY key, opaque* data, int data_size) {
+ uint16 n_Y;
+ size_t _n_Y;
+ MPI g, p;
+ int bits;
+ const RSA_SERVER_CREDENTIALS * cred;
+
+ cred = _gnutls_get_cred(key, GNUTLS_X509PKI, NULL);
+ if (cred == NULL) {
+ gnutls_assert();
+ return GNUTLS_E_INSUFICIENT_CRED;
+ }
+
+ ret =
+ _gnutls_get_rsa_params(key, ¶ms, cred->cert_list[0]);
+
+ if (ret < 0) {
+ gnutls_assert();
+ return ret;
+ }
+
+#if 0 /* removed. I do not know why - maybe I didn't get the protocol,
+ * but openssl does not use that byte
+ */
+ if (data[0] != 1) {
+ gnutls_assert();
+ return GNUTLS_E_UNIMPLEMENTED_FEATURE;
+ }
+#endif
+
+ n_Y = READuint16( &data[0]);
+
+ _n_Y = n_Y;
+ if (gcry_mpi_scan(&key->client_Y,
+ GCRYMPI_FMT_USG, &data[2], &_n_Y)) {
+ gnutls_assert();
+ return GNUTLS_E_MPI_SCAN_FAILED;
+ }
+
+ g = gnutls_get_dh_params(&p, bits);
+ key->KEY = gnutls_calc_dh_key( key->client_Y, key->dh_secret, p);
+
+ gnutls_mpi_release(key->client_Y);
+ gnutls_mpi_release(key->dh_secret);
+ gnutls_mpi_release(p);
+ gnutls_mpi_release(g);
+ key->client_Y = NULL;
+ key->dh_secret = NULL;
+
+ return 0;
+}
#include "auth_anon.h"
/* #include "auth_dhe_dss.h" */
#include "auth_srp.h"
+#include "auth_x509.h"
#define MAX_CIPHER 256
#define MAX_MAC 256
static const gnutls_kx_algo_entry kx_algorithms[] = {
GNUTLS_KX_ALGO_ENTRY(GNUTLS_KX_DH_ANON, 0, 0, 0, 1,
&anon_auth_struct),
- GNUTLS_KX_ALGO_ENTRY(GNUTLS_KX_RSA, 1, 1, 1, 0, NULL),
+ GNUTLS_KX_ALGO_ENTRY(GNUTLS_KX_RSA, 1, 1, 1, 0, &x509pki_auth_struct),
/* GNUTLS_KX_ALGO_ENTRY(GNUTLS_KX_DHE_DSS, 1, 1, 0, 0,
&dhe_dss_auth_struct),*/
- GNUTLS_KX_ALGO_ENTRY(GNUTLS_KX_DHE_RSA, 1, 1, 0, 0, NULL),
- GNUTLS_KX_ALGO_ENTRY(GNUTLS_KX_DH_DSS, 1, 1, 0, 0, NULL),
- GNUTLS_KX_ALGO_ENTRY(GNUTLS_KX_DH_RSA, 1, 1, 0, 0, NULL),
+/* GNUTLS_KX_ALGO_ENTRY(GNUTLS_KX_DHE_RSA, 1, 1, 0, 0, NULL),*/
+/* GNUTLS_KX_ALGO_ENTRY(GNUTLS_KX_DH_DSS, 1, 1, 0, 0, NULL),*/
+/* GNUTLS_KX_ALGO_ENTRY(GNUTLS_KX_DH_RSA, 1, 1, 0, 0, NULL),*/
GNUTLS_KX_ALGO_ENTRY(GNUTLS_KX_SRP, 0, 0, 0, 0, &srp_auth_struct),
{0}
};
return ret;
}
-/**
+ /*
* gnutls_handshake_begin - This function does a partial handshake of the TLS/SSL protocol.
* @cd: is a connection descriptor, as returned by socket().
* @state: is a a &GNUTLS_STATE structure.
*
+ * NOTE: I intend to make this function obsolete. If a certificate
+ * cannot be verified then this information will be available in the auth_info
+ * structure. Thus not need for these functions.
+ *
* This function initiates the handshake of the TLS/SSL protocol.
* Here we will receive - if requested and supported by the ciphersuite -
* the peer's certificate.
* However this failure will not be fatal. However you may choose to
* continue the handshake - eg. even if the certificate cannot
* be verified- by calling gnutls_handshake_finish().
- **/
+ */
int gnutls_handshake_begin(int cd, GNUTLS_STATE state)
{
int ret;
return ret;
}
- /* FIXME: send our certificate - if required */
/* NOTE: these should not be send if we are resuming */
/* SEND CERTIFICATE + KEYEXCHANGE + CERTIFICATE_REQUEST */
+ if (state->gnutls_internals.resumed == RESUME_FALSE)
+ ret = _gnutls_send_certificate(cd, state);
+ if (ret < 0) {
+ ERR("send server certificate", ret);
+ gnutls_assert();
+ gnutls_clearHashDataBuffer(state);
+ return ret;
+ }
+
+
/* send server key exchange (A) */
if (state->gnutls_internals.resumed == RESUME_FALSE)
ret = _gnutls_send_server_kx_message(cd, state);
return ret;
}
+ /* FIXME: Send certificate request */
+
/* Added for SRP which uses a different handshake */
/* receive the client key exchange message */
if (state->gnutls_internals.resumed == RESUME_FALSE) /* if we are not resuming */
}
}
-/* This function sends the final handshake packets and initializes connection */
+/* This function sends the final handshake packets and initializes connection
+ */
static int _gnutls_send_handshake_final(int cd, GNUTLS_STATE state,
int init)
{
return ret;
}
-/* This function receives the final handshake packets */
+/* This function receives the final handshake packets
+ */
static int _gnutls_recv_handshake_final(int cd, GNUTLS_STATE state,
int init)
{
return ret;
}
-/**
+ /*
* gnutls_handshake_finish - This function finished a partial handshake of the TLS/SSL protocol.
* @cd: is a connection descriptor, as returned by socket().
* @state: is a a &GNUTLS_STATE structure.
* You should call it only if you used gnutls_handshake_begin() and
* you have somehow verified the identity of the peer.
* This function will fail if any problem is encountered.
- **/
+ */
int gnutls_handshake_finish(int cd, GNUTLS_STATE state)
{
int ret = 0;