/* This function reads the RSA parameters from peer's certificate;
*/
-static int _gnutls_get_public_rsa_params(GNUTLS_STATE state)
+static int _gnutls_get_public_rsa_params(GNUTLS_STATE state, MPI params[RSA_PUBLIC_PARAMS])
{
int ret;
CERTIFICATE_AUTH_INFO info = _gnutls_get_auth_info( state);
return GNUTLS_E_UNKNOWN_ERROR;
}
-
+ memcpy( params, peer_cert.params, sizeof(MPI)*RSA_PUBLIC_PARAMS);
+
+/*
state->gnutls_key->a =
gcry_mpi_copy( peer_cert.params[0]);
if (state->gnutls_key->a==NULL) {
gnutls_free_cert( peer_cert);
return GNUTLS_E_MEMORY_ERROR;
}
+*/
return 0;
}
/* This function reads the RSA parameters from the private key
*/
-static int _gnutls_get_private_rsa_params(GNUTLS_STATE state)
+static int _gnutls_get_private_rsa_params(GNUTLS_STATE state, MPI params[RSA_PRIVATE_PARAMS])
{
int index;
const GNUTLS_CERTIFICATE_CREDENTIALS cred;
return GNUTLS_E_UNKNOWN_ERROR;
}
+ memcpy( params, cred->pkey[index].params, sizeof(MPI)*RSA_PRIVATE_PARAMS);
+
+/*
state->gnutls_key->u = gcry_mpi_copy( cred->pkey[index].params[2]);
if (state->gnutls_key->u==NULL) return GNUTLS_E_MEMORY_ERROR;
_gnutls_mpi_release( &state->gnutls_key->u);
return GNUTLS_E_MEMORY_ERROR;
}
+*/
return 0;
}
gnutls_sdatum plaintext;
gnutls_datum ciphertext;
int ret, dsize;
- MPI params[RSA_PARAMS];
+ MPI params[RSA_PRIVATE_PARAMS];
if (gnutls_protocol_get_version(state) == GNUTLS_SSL3) {
/* SSL 3.0 */
ciphertext.size = dsize;
}
- ret = _gnutls_get_private_rsa_params(state);
+ ret = _gnutls_get_private_rsa_params(state, params);
if (ret < 0) {
gnutls_assert();
return ret;
}
- params[0] = state->gnutls_key->A;
- params[1] = state->gnutls_key->u;
ret = _gnutls_pkcs1_rsa_decrypt(&plaintext, ciphertext, params, 2); /* btype==2 */
if (ret < 0 || plaintext.size != TLS_MASTER_SIZE) {
state->gnutls_key->key.size = plaintext.size;
}
- _gnutls_mpi_release(&state->gnutls_key->A);
_gnutls_mpi_release(&state->gnutls_key->B);
- _gnutls_mpi_release(&state->gnutls_key->u);
return ret;
}
{
CERTIFICATE_AUTH_INFO auth = state->gnutls_key->auth_info;
gnutls_datum sdata; /* data to send */
- MPI params[RSA_PARAMS];
+ MPI params[RSA_PUBLIC_PARAMS];
int ret;
GNUTLS_Version ver;
/* move RSA parameters to gnutls_key (state).
*/
if ((ret =
- _gnutls_get_public_rsa_params(state)) < 0) {
+ _gnutls_get_public_rsa_params(state, params)) < 0) {
gnutls_assert();
return ret;
}
- params[0] = state->gnutls_key->a;
- params[1] = state->gnutls_key->x;
if ((ret =
_gnutls_pkcs1_rsa_encrypt(&sdata, state->gnutls_key->key,
params, 2)) < 0) {
gnutls_assert();
return ret;
}
- _gnutls_mpi_release(&state->gnutls_key->a);
- _gnutls_mpi_release(&state->gnutls_key->x);
-
if (gnutls_protocol_get_version( state) == GNUTLS_SSL3) {
/* SSL 3.0 */
/*
- * Copyright (C) 2001 Nikos Mavroyanopoulos
+ * Copyright (C) 2001,2002 Nikos Mavroyanopoulos
*
* This file is part of GNUTLS.
*
static int _gnutls_pk_sign(int algo, MPI* data, MPI hash, MPI * pkey);
static int _gnutls_pk_verify(int algo, MPI hash, MPI* data, MPI *pkey);
+static int _gnutls_pk_decrypt(int algo, MPI * resarr, MPI data, MPI * pkey);
/* Do PKCS-1 RSA encryption.
int k, psize, i, ret, pad;
MPI m, res;
opaque *edata, *ps;
- MPI tmp_params[RSA_PARAMS];
+ MPI tmp_params[RSA_PUBLIC_PARAMS];
k = gcry_mpi_get_nbits(params[0]) / 8;
gnutls_free(edata);
ret = _gnutls_pk_encrypt(GCRY_PK_RSA, &res, m, tmp_params);
+
_gnutls_mpi_release(&m);
if (ret < 0) {
return GNUTLS_E_MPI_SCAN_FAILED;
}
- ret = _gnutls_pk_encrypt(GCRY_PK_RSA, &res, c, params);
+ ret = _gnutls_pk_decrypt(GCRY_PK_RSA, &res, c, params);
_gnutls_mpi_release(&c);
if (ret < 0) {
return rc;
}
+static int _gnutls_pk_decrypt(int algo, MPI * resarr, MPI data, MPI * pkey)
+{
+ GCRY_SEXP s_plain, s_data, s_pkey;
+ int rc;
+
+ /* make a sexp from pkey */
+ switch (algo) {
+ case GCRY_PK_RSA:
+ rc = gcry_sexp_build(&s_pkey, NULL,
+ "(private-key(rsa((n%m)(e%m)(d%m)(p%m)(q%m)(u%m))))",
+ pkey[0], pkey[1], pkey[2], pkey[3], pkey[4], pkey[5]);
+
+ break;
+
+ default:
+ gnutls_assert();
+ return GNUTLS_E_UNKNOWN_KX_ALGORITHM;
+ }
+
+ if (rc != 0) {
+ gnutls_assert();
+ return GNUTLS_E_UNKNOWN_ERROR;
+ }
+
+ /* put the data into a simple list */
+ if (gcry_sexp_build(&s_data, NULL, "(enc-val(rsa(a%m)))", data)) {
+ gnutls_assert();
+ gcry_sexp_release(s_pkey);
+ return GNUTLS_E_UNKNOWN_ERROR;
+ }
+
+ /* pass it to libgcrypt */
+ rc = gcry_pk_decrypt(&s_plain, s_data, s_pkey);
+ gcry_sexp_release(s_data);
+ gcry_sexp_release(s_pkey);
+
+ if (rc != 0) {
+ gnutls_assert();
+ return GNUTLS_E_PK_ENCRYPTION_FAILED;
+
+ } else { /* add better error handling or make gnupg use S-Exp directly */
+ resarr[0] = gcry_sexp_nth_mpi(s_plain, 0, 0);
+
+ if (resarr[0] == NULL) {
+ gnutls_assert();
+ gcry_sexp_release(s_plain);
+ return GNUTLS_E_INTERNAL_ERROR;
+ }
+ }
+
+ gcry_sexp_release(s_plain);
+ return rc;
+}
+
+
/* in case of DSA puts into data, r,s
*/
static
/* Converts an RSA PKCS#1 key to
* an internal structure (gnutls_private_key)
*/
-int _gnutls_PKCS1key2gnutlsKey(gnutls_private_key * pkey, gnutls_datum raw_key) {
+int _gnutls_PKCS1key2gnutlsKey(gnutls_private_key * pkey,
+ gnutls_datum raw_key)
+{
int result;
opaque str[MAX_PARAMETER_SIZE];
node_asn *pkey_asn;
-
+
pkey->pk_algorithm = GNUTLS_PK_RSA;
-
- if ((result=asn1_create_structure( _gnutls_get_gnutls_asn(), "GNUTLS.RSAPrivateKey", &pkey_asn, "rsakey"))!=ASN_OK) {
+
+ if ((result =
+ asn1_create_structure(_gnutls_get_gnutls_asn(),
+ "GNUTLS.RSAPrivateKey", &pkey_asn,
+ "rsakey")) != ASN_OK) {
gnutls_assert();
return result;
}
- if ((sizeof( pkey->params)/sizeof(MPI)) < RSA_PARAMS) {
+ if ((sizeof(pkey->params) / sizeof(MPI)) < RSA_PRIVATE_PARAMS) {
gnutls_assert();
/* internal error. Increase the MPIs in params */
return GNUTLS_E_INTERNAL_ERROR;
}
- result = asn1_get_der( pkey_asn, raw_key.data, raw_key.size);
+ result = asn1_get_der(pkey_asn, raw_key.data, raw_key.size);
if (result != ASN_OK) {
gnutls_assert();
return result;
}
- if ( (result=_gnutls_x509_read_int( pkey_asn, "rsakey.modulus",
- str, sizeof(str)-1, &pkey->params[0])) < 0) {
+ if ((result = _gnutls_x509_read_int(pkey_asn, "rsakey.modulus",
+ str, sizeof(str) - 1,
+ &pkey->params[0])) < 0) {
gnutls_assert();
asn1_delete_structure(pkey_asn);
return result;
}
- if ( (result=_gnutls_x509_read_int( pkey_asn, "rsakey.publicExponent",
- str, sizeof(str)-1, &pkey->params[1])) < 0) {
+ if ((result =
+ _gnutls_x509_read_int(pkey_asn, "rsakey.publicExponent", str,
+ sizeof(str) - 1,
+ &pkey->params[1])) < 0) {
gnutls_assert();
asn1_delete_structure(pkey_asn);
- _gnutls_mpi_release( &pkey->params[0]);
+ _gnutls_mpi_release(&pkey->params[0]);
+ return result;
+ }
+
+ if ((result =
+ _gnutls_x509_read_int(pkey_asn, "rsakey.privateExponent", str,
+ sizeof(str) - 1,
+ &pkey->params[2])) < 0) {
+ gnutls_assert();
+ _gnutls_mpi_release(&pkey->params[0]);
+ _gnutls_mpi_release(&pkey->params[1]);
+ asn1_delete_structure(pkey_asn);
return result;
}
- if ( (result=_gnutls_x509_read_int( pkey_asn, "rsakey.privateExponent",
- str, sizeof(str)-1, &pkey->params[2])) < 0) {
+ if ((result = _gnutls_x509_read_int(pkey_asn, "rsakey.prime1",
+ str, sizeof(str) - 1,
+ &pkey->params[3])) < 0) {
+ gnutls_assert();
+ _gnutls_mpi_release(&pkey->params[0]);
+ _gnutls_mpi_release(&pkey->params[1]);
+ _gnutls_mpi_release(&pkey->params[2]);
+ asn1_delete_structure(pkey_asn);
+ return result;
+ }
+
+ if ((result = _gnutls_x509_read_int(pkey_asn, "rsakey.prime2",
+ str, sizeof(str) - 1,
+ &pkey->params[4])) < 0) {
+ gnutls_assert();
+ _gnutls_mpi_release(&pkey->params[0]);
+ _gnutls_mpi_release(&pkey->params[1]);
+ _gnutls_mpi_release(&pkey->params[2]);
+ _gnutls_mpi_release(&pkey->params[3]);
+ asn1_delete_structure(pkey_asn);
+ return result;
+ }
+
+#if 1
+ /* Calculate the coefficient. This is because the gcrypt
+ * library is uses the p,q in the reverse order.
+ */
+ pkey->params[5] =
+ gcry_mpi_snew(gcry_mpi_get_nbits(pkey->params[0]));
+
+ if (pkey->params[5] == NULL) {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+
+ _gcry_mpi_invm(pkey->params[5], pkey->params[3], pkey->params[4]);
+ /* p, q */
+#else
+ if ( (result=_gnutls_x509_read_int( pkey_asn, "rsakey.coefficient",
+ str, sizeof(str)-1, &pkey->params[5])) < 0) {
gnutls_assert();
_gnutls_mpi_release( &pkey->params[0]);
_gnutls_mpi_release( &pkey->params[1]);
+ _gnutls_mpi_release( &pkey->params[2]);
+ _gnutls_mpi_release( &pkey->params[3]);
+ _gnutls_mpi_release( &pkey->params[4]);
asn1_delete_structure(pkey_asn);
return result;
}
- pkey->params_size = RSA_PARAMS;
+#endif
+
+ pkey->params_size = RSA_PRIVATE_PARAMS;
asn1_delete_structure(pkey_asn);
- if (gnutls_set_datum( &pkey->raw, raw_key.data, raw_key.size) < 0) {
+ if (gnutls_set_datum(&pkey->raw, raw_key.data, raw_key.size) < 0) {
_gnutls_mpi_release(&pkey->params[0]);
_gnutls_mpi_release(&pkey->params[1]);
_gnutls_mpi_release(&pkey->params[2]);
+ _gnutls_mpi_release(&pkey->params[3]);
+ _gnutls_mpi_release(&pkey->params[4]);
+ _gnutls_mpi_release(&pkey->params[5]);
gnutls_assert();
return GNUTLS_E_MEMORY_ERROR;
}
}
-int _gnutls_DSAkey2gnutlsKey(gnutls_private_key * pkey, gnutls_datum raw_key) {
+int _gnutls_DSAkey2gnutlsKey(gnutls_private_key * pkey,
+ gnutls_datum raw_key)
+{
int result;
opaque str[MAX_PARAMETER_SIZE];
node_asn *dsa_asn;
-
+
pkey->pk_algorithm = GNUTLS_PK_DSA;
-
- if ((result=asn1_create_structure( _gnutls_get_gnutls_asn(), "GNUTLS.DSAPrivateKey", &dsa_asn, "dsakey"))!=ASN_OK) {
+
+ if ((result =
+ asn1_create_structure(_gnutls_get_gnutls_asn(),
+ "GNUTLS.DSAPrivateKey", &dsa_asn,
+ "dsakey")) != ASN_OK) {
gnutls_assert();
return result;
}
- if ((sizeof( pkey->params)/sizeof(MPI)) < DSA_PRIVATE_PARAMS) {
+ if ((sizeof(pkey->params) / sizeof(MPI)) < DSA_PRIVATE_PARAMS) {
gnutls_assert();
/* internal error. Increase the MPIs in params */
return GNUTLS_E_INTERNAL_ERROR;
}
- result = asn1_get_der( dsa_asn, raw_key.data, raw_key.size);
+ result = asn1_get_der(dsa_asn, raw_key.data, raw_key.size);
if (result != ASN_OK) {
gnutls_assert();
return result;
}
- if ( (result=_gnutls_x509_read_int( dsa_asn, "dsakey.p",
- str, sizeof(str)-1, &pkey->params[0])) < 0) {
+ if ((result = _gnutls_x509_read_int(dsa_asn, "dsakey.p",
+ str, sizeof(str) - 1,
+ &pkey->params[0])) < 0) {
gnutls_assert();
asn1_delete_structure(dsa_asn);
return result;
}
- if ( (result=_gnutls_x509_read_int( dsa_asn, "dsakey.q",
- str, sizeof(str)-1, &pkey->params[1])) < 0) {
+ if ((result = _gnutls_x509_read_int(dsa_asn, "dsakey.q",
+ str, sizeof(str) - 1,
+ &pkey->params[1])) < 0) {
gnutls_assert();
asn1_delete_structure(dsa_asn);
- _gnutls_mpi_release( &pkey->params[0]);
+ _gnutls_mpi_release(&pkey->params[0]);
return result;
}
- if ( (result=_gnutls_x509_read_int( dsa_asn, "dsakey.g",
- str, sizeof(str)-1, &pkey->params[2])) < 0) {
+ if ((result = _gnutls_x509_read_int(dsa_asn, "dsakey.g",
+ str, sizeof(str) - 1,
+ &pkey->params[2])) < 0) {
gnutls_assert();
asn1_delete_structure(dsa_asn);
- _gnutls_mpi_release( &pkey->params[0]);
- _gnutls_mpi_release( &pkey->params[1]);
+ _gnutls_mpi_release(&pkey->params[0]);
+ _gnutls_mpi_release(&pkey->params[1]);
return result;
}
- if ( (result=_gnutls_x509_read_int( dsa_asn, "dsakey.Y",
- str, sizeof(str)-1, &pkey->params[3])) < 0) {
+ if ((result = _gnutls_x509_read_int(dsa_asn, "dsakey.Y",
+ str, sizeof(str) - 1,
+ &pkey->params[3])) < 0) {
gnutls_assert();
asn1_delete_structure(dsa_asn);
- _gnutls_mpi_release( &pkey->params[0]);
- _gnutls_mpi_release( &pkey->params[1]);
- _gnutls_mpi_release( &pkey->params[2]);
+ _gnutls_mpi_release(&pkey->params[0]);
+ _gnutls_mpi_release(&pkey->params[1]);
+ _gnutls_mpi_release(&pkey->params[2]);
return result;
}
- if ( (result=_gnutls_x509_read_int( dsa_asn, "dsakey.priv",
- str, sizeof(str)-1, &pkey->params[4])) < 0) {
+ if ((result = _gnutls_x509_read_int(dsa_asn, "dsakey.priv",
+ str, sizeof(str) - 1,
+ &pkey->params[4])) < 0) {
gnutls_assert();
asn1_delete_structure(dsa_asn);
- _gnutls_mpi_release( &pkey->params[0]);
- _gnutls_mpi_release( &pkey->params[1]);
- _gnutls_mpi_release( &pkey->params[2]);
- _gnutls_mpi_release( &pkey->params[3]);
+ _gnutls_mpi_release(&pkey->params[0]);
+ _gnutls_mpi_release(&pkey->params[1]);
+ _gnutls_mpi_release(&pkey->params[2]);
+ _gnutls_mpi_release(&pkey->params[3]);
return result;
}
pkey->params_size = DSA_PRIVATE_PARAMS;
asn1_delete_structure(dsa_asn);
- if (gnutls_set_datum( &pkey->raw, raw_key.data, raw_key.size) < 0) {
+ if (gnutls_set_datum(&pkey->raw, raw_key.data, raw_key.size) < 0) {
_gnutls_mpi_release(&pkey->params[0]);
_gnutls_mpi_release(&pkey->params[1]);
_gnutls_mpi_release(&pkey->params[2]);
}
-void _gnutls_free_private_key( gnutls_private_key pkey) {
-int i;
+void _gnutls_free_private_key(gnutls_private_key pkey)
+{
+ int i;
- for (i=0;i<pkey.params_size;i++) {
- _gnutls_mpi_release( &pkey.params[i]);
+ for (i = 0; i < pkey.params_size; i++) {
+ _gnutls_mpi_release(&pkey.params[i]);
}
- gnutls_free_datum( &pkey.raw);
+ gnutls_free_datum(&pkey.raw);
return;
}
-