summaryrefslogtreecommitdiff
path: root/lib/gnutls_pk.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/gnutls_pk.c')
-rw-r--r--lib/gnutls_pk.c1289
1 files changed, 658 insertions, 631 deletions
diff --git a/lib/gnutls_pk.c b/lib/gnutls_pk.c
index fa49381d96..fce507b6de 100644
--- a/lib/gnutls_pk.c
+++ b/lib/gnutls_pk.c
@@ -36,162 +36,173 @@
#include <x509/mpi.h>
#include <x509/common.h>
-static int _gnutls_pk_encrypt(int algo, mpi_t * resarr, mpi_t data, mpi_t * pkey, int pkey_len);
-static int _gnutls_pk_sign(int algo, mpi_t* data, mpi_t hash, mpi_t * pkey, int);
-static int _gnutls_pk_verify(int algo, mpi_t hash, mpi_t* data, mpi_t *pkey, int);
-static int _gnutls_pk_decrypt(int algo, mpi_t * resarr, mpi_t data, mpi_t * pkey, int);
+static int _gnutls_pk_encrypt(int algo, mpi_t * resarr, mpi_t data,
+ mpi_t * pkey, int pkey_len);
+static int _gnutls_pk_sign(int algo, mpi_t * data, mpi_t hash,
+ mpi_t * pkey, int);
+static int _gnutls_pk_verify(int algo, mpi_t hash, mpi_t * data,
+ mpi_t * pkey, int);
+static int _gnutls_pk_decrypt(int algo, mpi_t * resarr, mpi_t data,
+ mpi_t * pkey, int);
/* Do PKCS-1 RSA encryption.
* params is modulus, public exp.
*/
int _gnutls_pkcs1_rsa_encrypt(gnutls_datum * ciphertext,
- const gnutls_datum *plaintext, mpi_t* params,
- uint params_len,
- uint btype)
+ const gnutls_datum * plaintext,
+ mpi_t * params, uint params_len, uint btype)
{
- unsigned int i, pad;
- int ret;
- mpi_t m, res;
- opaque *edata, *ps;
- size_t k, psize;
- size_t mod_bits;
-
- mod_bits = _gnutls_mpi_get_nbits(params[0]);
- k = mod_bits / 8;
- if ( mod_bits % 8 != 0) k++;
-
- if (plaintext->size > k - 11) {
- gnutls_assert();
- return GNUTLS_E_PK_ENCRYPTION_FAILED;
- }
-
- edata = gnutls_alloca(k);
- if (edata == NULL) {
- gnutls_assert();
- return GNUTLS_E_MEMORY_ERROR;
- }
-
- /* EB = 00||BT||PS||00||D
- * (use block type 'btype')
- */
-
- edata[0] = 0;
- edata[1] = btype;
- psize = k - 3 - plaintext->size;
-
- ps = &edata[2];
- switch (btype) {
- case 2:
- /* using public key */
- if (params_len < RSA_PUBLIC_PARAMS) {
- gnutls_assert();
- gnutls_afree(edata);
- return GNUTLS_E_INTERNAL_ERROR;
- }
-
- if ( (ret=_gnutls_get_random(ps, psize, GNUTLS_STRONG_RANDOM)) < 0) {
- gnutls_assert();
- gnutls_afree(edata);
- return ret;
- }
- for (i = 0; i < psize; i++) {
- opaque rnd[3];
-
- /* Read three random bytes that will be
- * used to replace the zeros.
- */
- if ( (ret=_gnutls_get_random( rnd, 3, GNUTLS_STRONG_RANDOM)) < 0) {
- gnutls_assert();
- gnutls_afree(edata);
- return ret;
- }
- /* use non zero values for
- * the first two.
- */
- if (rnd[0]==0) rnd[0] = 0xaf;
- if (rnd[1]==0) rnd[1] = 0xae;
-
- if (ps[i] == 0) {
- /* If the first one is zero then set it to rnd[0].
- * If the second one is zero then set it to rnd[1].
- * Otherwise add (mod 256) the two previous ones plus rnd[3], or use
- * rnd[1] if the value == 0.
- */
- if (i<2) ps[i] = rnd[i];
- else ps[i] = GMAX( rnd[3] + ps[i-1] + ps[i-2], rnd[1]);
- }
- }
- break;
- case 1:
- /* using private key */
-
- if (params_len < RSA_PRIVATE_PARAMS) {
- gnutls_assert();
- gnutls_afree(edata);
- return GNUTLS_E_INTERNAL_ERROR;
- }
-
- for (i = 0; i < psize; i++)
- ps[i] = 0xff;
- break;
- default:
- gnutls_assert();
- gnutls_afree(edata);
- return GNUTLS_E_INTERNAL_ERROR;
- }
-
- ps[psize] = 0;
- memcpy(&ps[psize + 1], plaintext->data, plaintext->size);
-
- if (_gnutls_mpi_scan(&m, edata, &k) != 0) {
+ unsigned int i, pad;
+ int ret;
+ mpi_t m, res;
+ opaque *edata, *ps;
+ size_t k, psize;
+ size_t mod_bits;
+
+ mod_bits = _gnutls_mpi_get_nbits(params[0]);
+ k = mod_bits / 8;
+ if (mod_bits % 8 != 0)
+ k++;
+
+ if (plaintext->size > k - 11) {
+ gnutls_assert();
+ return GNUTLS_E_PK_ENCRYPTION_FAILED;
+ }
+
+ edata = gnutls_alloca(k);
+ if (edata == NULL) {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+
+ /* EB = 00||BT||PS||00||D
+ * (use block type 'btype')
+ */
+
+ edata[0] = 0;
+ edata[1] = btype;
+ psize = k - 3 - plaintext->size;
+
+ ps = &edata[2];
+ switch (btype) {
+ case 2:
+ /* using public key */
+ if (params_len < RSA_PUBLIC_PARAMS) {
+ gnutls_assert();
+ gnutls_afree(edata);
+ return GNUTLS_E_INTERNAL_ERROR;
+ }
+
+ if ((ret =
+ _gnutls_get_random(ps, psize, GNUTLS_STRONG_RANDOM)) < 0) {
+ gnutls_assert();
+ gnutls_afree(edata);
+ return ret;
+ }
+ for (i = 0; i < psize; i++) {
+ opaque rnd[3];
+
+ /* Read three random bytes that will be
+ * used to replace the zeros.
+ */
+ if ((ret =
+ _gnutls_get_random(rnd, 3, GNUTLS_STRONG_RANDOM)) < 0) {
gnutls_assert();
gnutls_afree(edata);
- return GNUTLS_E_MPI_SCAN_FAILED;
- }
- gnutls_afree(edata);
-
- if (btype==2) /* encrypt */
- ret = _gnutls_pk_encrypt(GCRY_PK_RSA, &res, m, params, params_len);
- else /* sign */
- ret = _gnutls_pk_sign(GCRY_PK_RSA, &res, m, params, params_len);
-
- _gnutls_mpi_release(&m);
-
- if (ret < 0) {
- gnutls_assert();
return ret;
- }
+ }
+ /* use non zero values for
+ * the first two.
+ */
+ if (rnd[0] == 0)
+ rnd[0] = 0xaf;
+ if (rnd[1] == 0)
+ rnd[1] = 0xae;
+
+ if (ps[i] == 0) {
+ /* If the first one is zero then set it to rnd[0].
+ * If the second one is zero then set it to rnd[1].
+ * Otherwise add (mod 256) the two previous ones plus rnd[3], or use
+ * rnd[1] if the value == 0.
+ */
+ if (i < 2)
+ ps[i] = rnd[i];
+ else
+ ps[i] = GMAX(rnd[3] + ps[i - 1] + ps[i - 2], rnd[1]);
+ }
+ }
+ break;
+ case 1:
+ /* using private key */
+
+ if (params_len < RSA_PRIVATE_PARAMS) {
+ gnutls_assert();
+ gnutls_afree(edata);
+ return GNUTLS_E_INTERNAL_ERROR;
+ }
+
+ for (i = 0; i < psize; i++)
+ ps[i] = 0xff;
+ break;
+ default:
+ gnutls_assert();
+ gnutls_afree(edata);
+ return GNUTLS_E_INTERNAL_ERROR;
+ }
- _gnutls_mpi_print(NULL, &psize, res);
+ ps[psize] = 0;
+ memcpy(&ps[psize + 1], plaintext->data, plaintext->size);
- if (psize < k) {
- /* padding psize */
- pad = k - psize;
- psize = k;
- } else if (psize==k) {
- pad = 0;
- } else { /* psize > k !!! */
- /* This is an impossible situation */
- gnutls_assert();
- _gnutls_mpi_release(&res);
- return GNUTLS_E_INTERNAL_ERROR;
- }
+ if (_gnutls_mpi_scan(&m, edata, &k) != 0) {
+ gnutls_assert();
+ gnutls_afree(edata);
+ return GNUTLS_E_MPI_SCAN_FAILED;
+ }
+ gnutls_afree(edata);
+
+ if (btype == 2) /* encrypt */
+ ret = _gnutls_pk_encrypt(GCRY_PK_RSA, &res, m, params, params_len);
+ else /* sign */
+ ret = _gnutls_pk_sign(GCRY_PK_RSA, &res, m, params, params_len);
+
+ _gnutls_mpi_release(&m);
+
+ if (ret < 0) {
+ gnutls_assert();
+ return ret;
+ }
+
+ _gnutls_mpi_print(NULL, &psize, res);
+
+ if (psize < k) {
+ /* padding psize */
+ pad = k - psize;
+ psize = k;
+ } else if (psize == k) {
+ pad = 0;
+ } else { /* psize > k !!! */
+ /* This is an impossible situation */
+ gnutls_assert();
+ _gnutls_mpi_release(&res);
+ return GNUTLS_E_INTERNAL_ERROR;
+ }
- ciphertext->data = gnutls_malloc(psize);
- if (ciphertext->data == NULL) {
- gnutls_assert();
- _gnutls_mpi_release(&res);
- return GNUTLS_E_MEMORY_ERROR;
- }
- _gnutls_mpi_print( &ciphertext->data[pad], &psize, res);
- for (i=0;i<pad;i++) ciphertext->data[i] = 0;
+ ciphertext->data = gnutls_malloc(psize);
+ if (ciphertext->data == NULL) {
+ gnutls_assert();
+ _gnutls_mpi_release(&res);
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+ _gnutls_mpi_print(&ciphertext->data[pad], &psize, res);
+ for (i = 0; i < pad; i++)
+ ciphertext->data[i] = 0;
- ciphertext->size = k;
+ ciphertext->size = k;
- _gnutls_mpi_release(&res);
+ _gnutls_mpi_release(&res);
- return 0;
+ return 0;
}
@@ -200,309 +211,322 @@ int _gnutls_pkcs1_rsa_encrypt(gnutls_datum * ciphertext,
* Can decrypt block type 1 and type 2 packets.
*/
int _gnutls_pkcs1_rsa_decrypt(gnutls_datum * plaintext,
- const gnutls_datum *ciphertext, mpi_t* params, uint params_len,
- uint btype)
+ const gnutls_datum * ciphertext,
+ mpi_t * params, uint params_len, uint btype)
{
- uint k, i;
- int ret;
- mpi_t c, res;
- opaque *edata;
- size_t esize, mod_bits;
-
- mod_bits = _gnutls_mpi_get_nbits(params[0]);
- k = mod_bits / 8;
- if ( mod_bits % 8 != 0) k++;
-
- esize = ciphertext->size;
-
- if (esize != k) {
- gnutls_assert();
- return GNUTLS_E_PK_DECRYPTION_FAILED;
- }
-
- if (_gnutls_mpi_scan(&c, ciphertext->data, &esize) != 0) {
- gnutls_assert();
- return GNUTLS_E_MPI_SCAN_FAILED;
- }
-
- /* we can use btype to see if the private key is
- * available.
- */
- if (btype==2)
- ret = _gnutls_pk_decrypt(GCRY_PK_RSA, &res, c, params, params_len);
- else {
- ret = _gnutls_pk_encrypt(GCRY_PK_RSA, &res, c, params, params_len);
- }
- _gnutls_mpi_release(&c);
-
- if (ret < 0) {
- gnutls_assert();
- return ret;
- }
-
- _gnutls_mpi_print(NULL, &esize, res);
- edata = gnutls_alloca(esize + 1);
- if (edata == NULL) {
- gnutls_assert();
- _gnutls_mpi_release(&res);
- return GNUTLS_E_MEMORY_ERROR;
- }
- _gnutls_mpi_print(&edata[1], &esize, res);
-
+ uint k, i;
+ int ret;
+ mpi_t c, res;
+ opaque *edata;
+ size_t esize, mod_bits;
+
+ mod_bits = _gnutls_mpi_get_nbits(params[0]);
+ k = mod_bits / 8;
+ if (mod_bits % 8 != 0)
+ k++;
+
+ esize = ciphertext->size;
+
+ if (esize != k) {
+ gnutls_assert();
+ return GNUTLS_E_PK_DECRYPTION_FAILED;
+ }
+
+ if (_gnutls_mpi_scan(&c, ciphertext->data, &esize) != 0) {
+ gnutls_assert();
+ return GNUTLS_E_MPI_SCAN_FAILED;
+ }
+
+ /* we can use btype to see if the private key is
+ * available.
+ */
+ if (btype == 2)
+ ret = _gnutls_pk_decrypt(GCRY_PK_RSA, &res, c, params, params_len);
+ else {
+ ret = _gnutls_pk_encrypt(GCRY_PK_RSA, &res, c, params, params_len);
+ }
+ _gnutls_mpi_release(&c);
+
+ if (ret < 0) {
+ gnutls_assert();
+ return ret;
+ }
+
+ _gnutls_mpi_print(NULL, &esize, res);
+ edata = gnutls_alloca(esize + 1);
+ if (edata == NULL) {
+ gnutls_assert();
_gnutls_mpi_release(&res);
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+ _gnutls_mpi_print(&edata[1], &esize, res);
- /* EB = 00||BT||PS||00||D
- * (use block type 'btype')
- */
+ _gnutls_mpi_release(&res);
+ /* EB = 00||BT||PS||00||D
+ * (use block type 'btype')
+ */
- edata[0] = 0;
- esize++;
- if (edata[0] != 0 || edata[1] != btype) {
- gnutls_assert();
- gnutls_afree(edata);
- return GNUTLS_E_DECRYPTION_FAILED;
- }
+ edata[0] = 0;
+ esize++;
- ret = GNUTLS_E_DECRYPTION_FAILED;
- switch (btype) {
- case 2:
- for (i = 2; i < esize; i++) {
- if (edata[i] == 0) {
- ret = 0;
- break;
- }
- }
- break;
- case 1:
- for (i = 2; i < esize; i++) {
- if (edata[i] == 0 && i > 2) {
- ret = 0;
- break;
- }
- if (edata[i] != 0xff) {
- _gnutls_handshake_log("PKCS #1 padding error");
- ret = GNUTLS_E_PKCS1_WRONG_PAD;
- break;
- }
- }
+ if (edata[0] != 0 || edata[1] != btype) {
+ gnutls_assert();
+ gnutls_afree(edata);
+ return GNUTLS_E_DECRYPTION_FAILED;
+ }
+
+ ret = GNUTLS_E_DECRYPTION_FAILED;
+ switch (btype) {
+ case 2:
+ for (i = 2; i < esize; i++) {
+ if (edata[i] == 0) {
+ ret = 0;
break;
- default:
- gnutls_assert();
- gnutls_afree(edata);
- return GNUTLS_E_INTERNAL_ERROR;
+ }
}
- i++;
-
- if (ret < 0) {
- gnutls_assert();
- gnutls_afree(edata);
- return GNUTLS_E_DECRYPTION_FAILED;
+ break;
+ case 1:
+ for (i = 2; i < esize; i++) {
+ if (edata[i] == 0 && i > 2) {
+ ret = 0;
+ break;
+ }
+ if (edata[i] != 0xff) {
+ _gnutls_handshake_log("PKCS #1 padding error");
+ ret = GNUTLS_E_PKCS1_WRONG_PAD;
+ break;
+ }
}
+ break;
+ default:
+ gnutls_assert();
+ gnutls_afree(edata);
+ return GNUTLS_E_INTERNAL_ERROR;
+ }
+ i++;
- if (_gnutls_sset_datum(plaintext, &edata[i], esize - i) < 0) {
- gnutls_assert();
- gnutls_afree(edata);
- return GNUTLS_E_MEMORY_ERROR;
- }
+ if (ret < 0) {
+ gnutls_assert();
+ gnutls_afree(edata);
+ return GNUTLS_E_DECRYPTION_FAILED;
+ }
+ if (_gnutls_sset_datum(plaintext, &edata[i], esize - i) < 0) {
+ gnutls_assert();
gnutls_afree(edata);
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+
+ gnutls_afree(edata);
- return 0;
+ return 0;
}
-int _gnutls_rsa_verify( const gnutls_datum* vdata, const gnutls_datum *ciphertext,
- mpi_t *params, int params_len, int btype) {
+int _gnutls_rsa_verify(const gnutls_datum * vdata,
+ const gnutls_datum * ciphertext, mpi_t * params,
+ int params_len, int btype)
+{
- gnutls_datum plain;
- int ret;
+ gnutls_datum plain;
+ int ret;
- /* decrypt signature */
- if ( (ret=_gnutls_pkcs1_rsa_decrypt( &plain, ciphertext, params, params_len, btype)) < 0) {
- gnutls_assert();
- return ret;
- }
+ /* decrypt signature */
+ if ((ret =
+ _gnutls_pkcs1_rsa_decrypt(&plain, ciphertext, params, params_len,
+ btype)) < 0) {
+ gnutls_assert();
+ return ret;
+ }
- if (plain.size != vdata->size) {
- gnutls_assert();
- _gnutls_free_datum( &plain);
- return GNUTLS_E_PK_SIG_VERIFY_FAILED;
- }
+ if (plain.size != vdata->size) {
+ gnutls_assert();
+ _gnutls_free_datum(&plain);
+ return GNUTLS_E_PK_SIG_VERIFY_FAILED;
+ }
- if ( memcmp(plain.data, vdata->data, plain.size)!=0) {
- gnutls_assert();
- _gnutls_free_datum( &plain);
- return GNUTLS_E_PK_SIG_VERIFY_FAILED;
- }
+ if (memcmp(plain.data, vdata->data, plain.size) != 0) {
+ gnutls_assert();
+ _gnutls_free_datum(&plain);
+ return GNUTLS_E_PK_SIG_VERIFY_FAILED;
+ }
- _gnutls_free_datum( &plain);
+ _gnutls_free_datum(&plain);
- return 0; /* ok */
+ return 0; /* ok */
}
/* encodes the Dss-Sig-Value structure
*/
-static int encode_ber_rs( gnutls_datum* sig_value, mpi_t r, mpi_t s) {
-ASN1_TYPE sig;
-int result, tot_len;
-
- if ((result=asn1_create_element( _gnutls_get_gnutls_asn(), "GNUTLS.DSASignatureValue",
- &sig))!=ASN1_SUCCESS) {
- gnutls_assert();
- return _gnutls_asn2err(result);
- }
+static int encode_ber_rs(gnutls_datum * sig_value, mpi_t r, mpi_t s)
+{
+ ASN1_TYPE sig;
+ int result, tot_len;
+
+ if ((result =
+ asn1_create_element(_gnutls_get_gnutls_asn(),
+ "GNUTLS.DSASignatureValue",
+ &sig)) != ASN1_SUCCESS) {
+ gnutls_assert();
+ return _gnutls_asn2err(result);
+ }
+
+ result = _gnutls_x509_write_int(sig, "r", r, 1);
+ if (result < 0) {
+ gnutls_assert();
+ asn1_delete_structure(&sig);
+ return result;
+ }
- result = _gnutls_x509_write_int( sig, "r", r, 1);
- if ( result < 0) {
- gnutls_assert();
- asn1_delete_structure(&sig);
- return result;
- }
+ result = _gnutls_x509_write_int(sig, "s", s, 1);
+ if (result < 0) {
+ gnutls_assert();
+ asn1_delete_structure(&sig);
+ return result;
+ }
- result = _gnutls_x509_write_int( sig, "s", s, 1);
- if (result < 0) {
- gnutls_assert();
- asn1_delete_structure(&sig);
- return result;
- }
+ tot_len = 0;
- tot_len = 0;
-
- result = _gnutls_x509_der_encode( sig, "", sig_value, 0);
+ result = _gnutls_x509_der_encode(sig, "", sig_value, 0);
- asn1_delete_structure(&sig);
+ asn1_delete_structure(&sig);
- if (result < 0) {
- gnutls_assert();
- return result;
- }
+ if (result < 0) {
+ gnutls_assert();
+ return result;
+ }
- return 0;
+ return 0;
}
/* Do DSA signature calculation. params is p, q, g, y, x in that order.
*/
-int _gnutls_dsa_sign(gnutls_datum * signature, const gnutls_datum *hash,
+int _gnutls_dsa_sign(gnutls_datum * signature, const gnutls_datum * hash,
mpi_t * params, uint params_len)
{
- mpi_t rs[2], mdata;
- int ret;
- size_t k;
-
- k = hash->size;
- if (k!=20) { /* SHA only */
- gnutls_assert();
- return GNUTLS_E_PK_SIGN_FAILED;
- }
-
- if (_gnutls_mpi_scan(&mdata, hash->data, &k) != 0) {
- gnutls_assert();
- return GNUTLS_E_MPI_SCAN_FAILED;
- }
-
- ret = _gnutls_pk_sign(GCRY_PK_DSA, rs, mdata, params, params_len);
- /* rs[0], rs[1] now hold r,s */
- _gnutls_mpi_release(&mdata);
-
- if (ret < 0) {
- gnutls_assert();
- return ret;
- }
-
- ret = encode_ber_rs( signature, rs[0], rs[1]);
-
- /* free r,s */
- _gnutls_mpi_release(&rs[0]);
- _gnutls_mpi_release(&rs[1]);
-
- if (ret!=0) {
- gnutls_assert();
- return GNUTLS_E_MEMORY_ERROR;
- }
-
- return 0;
+ mpi_t rs[2], mdata;
+ int ret;
+ size_t k;
+
+ k = hash->size;
+ if (k != 20) { /* SHA only */
+ gnutls_assert();
+ return GNUTLS_E_PK_SIGN_FAILED;
+ }
+
+ if (_gnutls_mpi_scan(&mdata, hash->data, &k) != 0) {
+ gnutls_assert();
+ return GNUTLS_E_MPI_SCAN_FAILED;
+ }
+
+ ret = _gnutls_pk_sign(GCRY_PK_DSA, rs, mdata, params, params_len);
+ /* rs[0], rs[1] now hold r,s */
+ _gnutls_mpi_release(&mdata);
+
+ if (ret < 0) {
+ gnutls_assert();
+ return ret;
+ }
+
+ ret = encode_ber_rs(signature, rs[0], rs[1]);
+
+ /* free r,s */
+ _gnutls_mpi_release(&rs[0]);
+ _gnutls_mpi_release(&rs[1]);
+
+ if (ret != 0) {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+
+ return 0;
}
/* decodes the Dss-Sig-Value structure
*/
-static int decode_ber_rs( const gnutls_datum* sig_value, mpi_t* r, mpi_t* s) {
-ASN1_TYPE sig;
-int result;
+static int decode_ber_rs(const gnutls_datum * sig_value, mpi_t * r,
+ mpi_t * s)
+{
+ ASN1_TYPE sig;
+ int result;
+
+ if ((result =
+ asn1_create_element(_gnutls_get_gnutls_asn(),
+ "GNUTLS.DSASignatureValue",
+ &sig)) != ASN1_SUCCESS) {
+ gnutls_assert();
+ return _gnutls_asn2err(result);
+ }
+
+ result =
+ asn1_der_decoding(&sig, sig_value->data, sig_value->size, NULL);
+ if (result != ASN1_SUCCESS) {
+ gnutls_assert();
+ asn1_delete_structure(&sig);
+ return _gnutls_asn2err(result);
+ }
- if ((result=asn1_create_element( _gnutls_get_gnutls_asn(), "GNUTLS.DSASignatureValue", &sig))!=ASN1_SUCCESS) {
- gnutls_assert();
- return _gnutls_asn2err(result);
- }
+ result = _gnutls_x509_read_int(sig, "r", r);
+ if (result < 0) {
+ gnutls_assert();
+ asn1_delete_structure(&sig);
+ return result;
+ }
- result = asn1_der_decoding( &sig, sig_value->data, sig_value->size, NULL);
- if (result != ASN1_SUCCESS) {
- gnutls_assert();
- asn1_delete_structure(&sig);
- return _gnutls_asn2err(result);
- }
-
- result =
- _gnutls_x509_read_int( sig, "r", r);
- if (result < 0) {
- gnutls_assert();
- asn1_delete_structure(&sig);
- return result;
- }
+ result = _gnutls_x509_read_int(sig, "s", s);
+ if (result < 0) {
+ gnutls_assert();
+ _gnutls_mpi_release(s);
+ asn1_delete_structure(&sig);
+ return result;
+ }
- result =
- _gnutls_x509_read_int( sig, "s", s);
- if (result < 0) {
- gnutls_assert();
- _gnutls_mpi_release( s);
- asn1_delete_structure(&sig);
- return result;
- }
+ asn1_delete_structure(&sig);
- asn1_delete_structure(&sig);
-
- return 0;
+ return 0;
}
/* params is p, q, g, y in that order
*/
-int _gnutls_dsa_verify( const gnutls_datum* vdata, const gnutls_datum *sig_value,
- mpi_t * params, int params_len) {
-
- mpi_t mdata;
- int ret;
- size_t k;
- mpi_t rs[2];
-
- if (vdata->size != 20) { /* sha-1 only */
- gnutls_assert();
- return GNUTLS_E_PK_SIG_VERIFY_FAILED;
- }
-
- if (decode_ber_rs( sig_value, &rs[0], &rs[1])!=0) {
- gnutls_assert();
- return GNUTLS_E_MPI_SCAN_FAILED;
- }
-
- k = vdata->size;
- if (_gnutls_mpi_scan(&mdata, vdata->data, &k) != 0) {
- gnutls_assert();
- return GNUTLS_E_MPI_SCAN_FAILED;
- }
-
- /* decrypt signature */
- ret=_gnutls_pk_verify( GCRY_PK_DSA, mdata, rs, params,
- params_len);
- _gnutls_mpi_release(&mdata);
-
- if (ret < 0) {
- gnutls_assert();
- return ret;
- }
+int _gnutls_dsa_verify(const gnutls_datum * vdata,
+ const gnutls_datum * sig_value, mpi_t * params,
+ int params_len)
+{
- return 0; /* ok */
+ mpi_t mdata;
+ int ret;
+ size_t k;
+ mpi_t rs[2];
+
+ if (vdata->size != 20) { /* sha-1 only */
+ gnutls_assert();
+ return GNUTLS_E_PK_SIG_VERIFY_FAILED;
+ }
+
+ if (decode_ber_rs(sig_value, &rs[0], &rs[1]) != 0) {
+ gnutls_assert();
+ return GNUTLS_E_MPI_SCAN_FAILED;
+ }
+
+ k = vdata->size;
+ if (_gnutls_mpi_scan(&mdata, vdata->data, &k) != 0) {
+ gnutls_assert();
+ return GNUTLS_E_MPI_SCAN_FAILED;
+ }
+
+ /* decrypt signature */
+ ret = _gnutls_pk_verify(GCRY_PK_DSA, mdata, rs, params, params_len);
+ _gnutls_mpi_release(&mdata);
+
+ if (ret < 0) {
+ gnutls_assert();
+ return ret;
+ }
+
+ return 0; /* ok */
}
@@ -513,295 +537,298 @@ int _gnutls_dsa_verify( const gnutls_datum* vdata, const gnutls_datum *sig_value
* Emulate our old PK interface here - sometime in the future we might
* change the internal design to directly fit to libgcrypt.
*/
-static int _gnutls_pk_encrypt(int algo, mpi_t * resarr, mpi_t data, mpi_t * pkey, int pkey_len)
+static int _gnutls_pk_encrypt(int algo, mpi_t * resarr, mpi_t data,
+ mpi_t * pkey, int pkey_len)
{
- gcry_sexp_t s_ciph, s_data, s_pkey;
- int rc=-1;
-
- /* make a sexp from pkey */
- switch (algo) {
- case GCRY_PK_RSA:
- if (pkey_len >= 2)
- rc = gcry_sexp_build(&s_pkey, NULL,
- "(public-key(rsa(n%m)(e%m)))",
- pkey[0], pkey[1]);
- break;
+ gcry_sexp_t s_ciph, s_data, s_pkey;
+ int rc = -1;
+
+ /* make a sexp from pkey */
+ switch (algo) {
+ case GCRY_PK_RSA:
+ if (pkey_len >= 2)
+ rc = gcry_sexp_build(&s_pkey, NULL,
+ "(public-key(rsa(n%m)(e%m)))",
+ pkey[0], pkey[1]);
+ break;
+
+ default:
+ gnutls_assert();
+ return GNUTLS_E_INTERNAL_ERROR;
+ }
+
+ if (rc != 0) {
+ gnutls_assert();
+ return GNUTLS_E_INTERNAL_ERROR;
+ }
+
+ /* put the data into a simple list */
+ if (gcry_sexp_build(&s_data, NULL, "%m", data)) {
+ gnutls_assert();
+ gcry_sexp_release(s_pkey);
+ return GNUTLS_E_INTERNAL_ERROR;
+ }
- default:
- gnutls_assert();
- return GNUTLS_E_INTERNAL_ERROR;
- }
+ /* pass it to libgcrypt */
+ rc = gcry_pk_encrypt(&s_ciph, s_data, s_pkey);
+ gcry_sexp_release(s_data);
+ gcry_sexp_release(s_pkey);
- if (rc != 0) {
- gnutls_assert();
- return GNUTLS_E_INTERNAL_ERROR;
- }
+ if (rc != 0) {
+ gnutls_assert();
+ return GNUTLS_E_PK_ENCRYPTION_FAILED;
- /* put the data into a simple list */
- if (gcry_sexp_build(&s_data, NULL, "%m", data)) {
- gnutls_assert();
- gcry_sexp_release(s_pkey);
- return GNUTLS_E_INTERNAL_ERROR;
+ } else { /* add better error handling or make gnupg use S-Exp directly */
+ gcry_sexp_t list = gcry_sexp_find_token(s_ciph, "a", 0);
+ if (list == NULL) {
+ gnutls_assert();
+ gcry_sexp_release(s_ciph);
+ return GNUTLS_E_INTERNAL_ERROR;
}
- /* pass it to libgcrypt */
- rc = gcry_pk_encrypt(&s_ciph, s_data, s_pkey);
- gcry_sexp_release(s_data);
- gcry_sexp_release(s_pkey);
+ resarr[0] = gcry_sexp_nth_mpi(list, 1, 0);
+ gcry_sexp_release(list);
- if (rc != 0) {
- gnutls_assert();
- return GNUTLS_E_PK_ENCRYPTION_FAILED;
-
- } else { /* add better error handling or make gnupg use S-Exp directly */
- gcry_sexp_t list = gcry_sexp_find_token(s_ciph, "a", 0);
- if (list == NULL) {
- gnutls_assert();
- gcry_sexp_release(s_ciph);
- return GNUTLS_E_INTERNAL_ERROR;
- }
-
- resarr[0] = gcry_sexp_nth_mpi(list, 1, 0);
- gcry_sexp_release(list);
-
- if (resarr[0] == NULL) {
- gnutls_assert();
- gcry_sexp_release(s_ciph);
- return GNUTLS_E_INTERNAL_ERROR;
- }
+ if (resarr[0] == NULL) {
+ gnutls_assert();
+ gcry_sexp_release(s_ciph);
+ return GNUTLS_E_INTERNAL_ERROR;
}
+ }
- gcry_sexp_release(s_ciph);
- return rc;
+ gcry_sexp_release(s_ciph);
+ return rc;
}
-static
-int _gnutls_pk_decrypt(int algo, mpi_t * resarr, mpi_t data, mpi_t * pkey, int pkey_len)
+static
+int _gnutls_pk_decrypt(int algo, mpi_t * resarr, mpi_t data, mpi_t * pkey,
+ int pkey_len)
{
- gcry_sexp_t s_plain, s_data, s_pkey;
- int rc=-1;
-
- /* make a sexp from pkey */
- switch (algo) {
- case GCRY_PK_RSA:
- if (pkey_len >=6)
- 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_INTERNAL_ERROR;
- }
-
- if (rc != 0) {
- gnutls_assert();
- return GNUTLS_E_INTERNAL_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_INTERNAL_ERROR;
- }
-
- /* pass it to libgcrypt */
- rc = gcry_pk_decrypt(&s_plain, s_data, s_pkey);
- gcry_sexp_release(s_data);
+ gcry_sexp_t s_plain, s_data, s_pkey;
+ int rc = -1;
+
+ /* make a sexp from pkey */
+ switch (algo) {
+ case GCRY_PK_RSA:
+ if (pkey_len >= 6)
+ 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_INTERNAL_ERROR;
+ }
+
+ if (rc != 0) {
+ gnutls_assert();
+ return GNUTLS_E_INTERNAL_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_INTERNAL_ERROR;
+ }
- if (rc != 0) {
- gnutls_assert();
- return GNUTLS_E_PK_DECRYPTION_FAILED;
+ /* pass it to libgcrypt */
+ rc = gcry_pk_decrypt(&s_plain, s_data, s_pkey);
+ gcry_sexp_release(s_data);
+ gcry_sexp_release(s_pkey);
- } else { /* add better error handling or make gnupg use S-Exp directly */
- resarr[0] = gcry_sexp_nth_mpi(s_plain, 0, 0);
+ if (rc != 0) {
+ gnutls_assert();
+ return GNUTLS_E_PK_DECRYPTION_FAILED;
- if (resarr[0] == NULL) {
- gnutls_assert();
- gcry_sexp_release(s_plain);
- return GNUTLS_E_INTERNAL_ERROR;
- }
+ } 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;
+ gcry_sexp_release(s_plain);
+ return rc;
}
/* in case of DSA puts into data, r,s
*/
-static
-int _gnutls_pk_sign(int algo, mpi_t* data, mpi_t hash, mpi_t * pkey, int pkey_len)
+static
+int _gnutls_pk_sign(int algo, mpi_t * data, mpi_t hash, mpi_t * pkey,
+ int pkey_len)
{
- gcry_sexp_t s_hash, s_key, s_sig;
- int rc=-1;
-
- /* make a sexp from pkey */
- switch (algo) {
- case GCRY_PK_DSA:
- if (pkey_len >= 5)
- rc = gcry_sexp_build(&s_key, NULL,
- "(private-key(dsa(p%m)(q%m)(g%m)(y%m)(x%m)))",
- pkey[0], pkey[1], pkey[2],
- pkey[3], pkey[4]);
- else {
- gnutls_assert();
- }
-
- break;
- case GCRY_PK_RSA:
- if (pkey_len >=6)
- rc = gcry_sexp_build(&s_key, 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]);
- else {
- gnutls_assert();
- }
- break;
-
- default:
- gnutls_assert();
- return GNUTLS_E_INTERNAL_ERROR;
+ gcry_sexp_t s_hash, s_key, s_sig;
+ int rc = -1;
+
+ /* make a sexp from pkey */
+ switch (algo) {
+ case GCRY_PK_DSA:
+ if (pkey_len >= 5)
+ rc = gcry_sexp_build(&s_key, NULL,
+ "(private-key(dsa(p%m)(q%m)(g%m)(y%m)(x%m)))",
+ pkey[0], pkey[1], pkey[2],
+ pkey[3], pkey[4]);
+ else {
+ gnutls_assert();
}
- if (rc != 0) {
- gnutls_assert();
- return GNUTLS_E_INTERNAL_ERROR;
+ break;
+ case GCRY_PK_RSA:
+ if (pkey_len >= 6)
+ rc = gcry_sexp_build(&s_key, 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]);
+ else {
+ gnutls_assert();
}
+ break;
- /* put the data into a simple list */
- if (gcry_sexp_build(&s_hash, NULL, "%m", hash)) {
- gnutls_assert();
- return GNUTLS_E_INTERNAL_ERROR;
- }
+ default:
+ gnutls_assert();
+ return GNUTLS_E_INTERNAL_ERROR;
+ }
- /* pass it to libgcrypt */
- rc = gcry_pk_sign(&s_sig, s_hash, s_key);
- gcry_sexp_release(s_hash);
- gcry_sexp_release(s_key);
+ if (rc != 0) {
+ gnutls_assert();
+ return GNUTLS_E_INTERNAL_ERROR;
+ }
- if (rc != 0) {
- gnutls_assert();
- return GNUTLS_E_PK_SIGN_FAILED;
-
- } else {
- gcry_sexp_t list;
-
- if (algo==GCRY_PK_DSA) {
- list = gcry_sexp_find_token( s_sig, "r" , 0);
- if (list == NULL) {
- gnutls_assert();
- gcry_sexp_release(s_sig);
- return GNUTLS_E_INTERNAL_ERROR;
- }
-
- data[0] = gcry_sexp_nth_mpi( list, 1, 0 );
- gcry_sexp_release (list);
-
- list = gcry_sexp_find_token( s_sig, "s" , 0);
- if (list == NULL) {
- gnutls_assert();
- gcry_sexp_release(s_sig);
- return GNUTLS_E_INTERNAL_ERROR;
- }
-
- data[1] = gcry_sexp_nth_mpi( list, 1, 0 );
- gcry_sexp_release (list);
- } else { /* GCRY_PK_RSA */
- list = gcry_sexp_find_token( s_sig, "s" , 0);
- if (list == NULL) {
- gnutls_assert();
- gcry_sexp_release(s_sig);
- return GNUTLS_E_INTERNAL_ERROR;
- }
-
- data[0] = gcry_sexp_nth_mpi( list, 1, 0 );
- gcry_sexp_release (list);
- }
- }
+ /* put the data into a simple list */
+ if (gcry_sexp_build(&s_hash, NULL, "%m", hash)) {
+ gnutls_assert();
+ return GNUTLS_E_INTERNAL_ERROR;
+ }
- gcry_sexp_release(s_sig);
- return 0;
-}
+ /* pass it to libgcrypt */
+ rc = gcry_pk_sign(&s_sig, s_hash, s_key);
+ gcry_sexp_release(s_hash);
+ gcry_sexp_release(s_key);
+ if (rc != 0) {
+ gnutls_assert();
+ return GNUTLS_E_PK_SIGN_FAILED;
-static int _gnutls_pk_verify(int algo, mpi_t hash, mpi_t* data, mpi_t *pkey, int pkey_len)
-{
- gcry_sexp_t s_sig, s_hash, s_pkey;
- int rc=-1;
-
- /* make a sexp from pkey */
- switch (algo) {
- case GCRY_PK_DSA:
- if (pkey_len >= 4)
- rc = gcry_sexp_build(&s_pkey, NULL,
- "(public-key(dsa(p%m)(q%m)(g%m)(y%m)))",
- pkey[0], pkey[1], pkey[2], pkey[3]);
- break;
- case GCRY_PK_RSA:
- if (pkey_len >= 2)
- rc = gcry_sexp_build(&s_pkey, NULL,
- "(public-key(rsa(n%m)(e%m)))",
- pkey[0], pkey[1]);
- break;
+ } else {
+ gcry_sexp_t list;
- default:
+ if (algo == GCRY_PK_DSA) {
+ list = gcry_sexp_find_token(s_sig, "r", 0);
+ if (list == NULL) {
gnutls_assert();
+ gcry_sexp_release(s_sig);
return GNUTLS_E_INTERNAL_ERROR;
- }
+ }
- if (rc != 0) {
- gnutls_assert();
- return GNUTLS_E_INTERNAL_ERROR;
- }
+ data[0] = gcry_sexp_nth_mpi(list, 1, 0);
+ gcry_sexp_release(list);
- /* put the data into a simple list */
- if (gcry_sexp_build(&s_hash, NULL, "%m", hash)) {
+ list = gcry_sexp_find_token(s_sig, "s", 0);
+ if (list == NULL) {
gnutls_assert();
- gcry_sexp_release(s_pkey);
+ gcry_sexp_release(s_sig);
return GNUTLS_E_INTERNAL_ERROR;
- }
+ }
- switch (algo) {
- case GCRY_PK_DSA:
- rc = gcry_sexp_build(&s_sig, NULL,
- "(sig-val(dsa(r%m)(s%m)))",
- data[0], data[1]);
- break;
- case GCRY_PK_RSA:
- rc = gcry_sexp_build(&s_sig, NULL,
- "(sig-val(rsa(s%m)))",
- data[0]);
- break;
-
- default:
+ data[1] = gcry_sexp_nth_mpi(list, 1, 0);
+ gcry_sexp_release(list);
+ } else { /* GCRY_PK_RSA */
+ list = gcry_sexp_find_token(s_sig, "s", 0);
+ if (list == NULL) {
gnutls_assert();
- gcry_sexp_release(s_pkey);
- gcry_sexp_release(s_hash);
+ gcry_sexp_release(s_sig);
return GNUTLS_E_INTERNAL_ERROR;
- }
+ }
- if (rc != 0) {
- gnutls_assert();
- gcry_sexp_release(s_pkey);
- gcry_sexp_release(s_hash);
- return GNUTLS_E_INTERNAL_ERROR;
+ data[0] = gcry_sexp_nth_mpi(list, 1, 0);
+ gcry_sexp_release(list);
}
+ }
- rc = gcry_pk_verify( s_sig, s_hash, s_pkey);
-
- gcry_sexp_release(s_sig);
+ gcry_sexp_release(s_sig);
+ return 0;
+}
+
+
+static int _gnutls_pk_verify(int algo, mpi_t hash, mpi_t * data,
+ mpi_t * pkey, int pkey_len)
+{
+ gcry_sexp_t s_sig, s_hash, s_pkey;
+ int rc = -1;
+
+ /* make a sexp from pkey */
+ switch (algo) {
+ case GCRY_PK_DSA:
+ if (pkey_len >= 4)
+ rc = gcry_sexp_build(&s_pkey, NULL,
+ "(public-key(dsa(p%m)(q%m)(g%m)(y%m)))",
+ pkey[0], pkey[1], pkey[2], pkey[3]);
+ break;
+ case GCRY_PK_RSA:
+ if (pkey_len >= 2)
+ rc = gcry_sexp_build(&s_pkey, NULL,
+ "(public-key(rsa(n%m)(e%m)))",
+ pkey[0], pkey[1]);
+ break;
+
+ default:
+ gnutls_assert();
+ return GNUTLS_E_INTERNAL_ERROR;
+ }
+
+ if (rc != 0) {
+ gnutls_assert();
+ return GNUTLS_E_INTERNAL_ERROR;
+ }
+
+ /* put the data into a simple list */
+ if (gcry_sexp_build(&s_hash, NULL, "%m", hash)) {
+ gnutls_assert();
+ gcry_sexp_release(s_pkey);
+ return GNUTLS_E_INTERNAL_ERROR;
+ }
+
+ switch (algo) {
+ case GCRY_PK_DSA:
+ rc = gcry_sexp_build(&s_sig, NULL,
+ "(sig-val(dsa(r%m)(s%m)))", data[0], data[1]);
+ break;
+ case GCRY_PK_RSA:
+ rc = gcry_sexp_build(&s_sig, NULL, "(sig-val(rsa(s%m)))", data[0]);
+ break;
+
+ default:
+ gnutls_assert();
+ gcry_sexp_release(s_pkey);
gcry_sexp_release(s_hash);
+ return GNUTLS_E_INTERNAL_ERROR;
+ }
+
+ if (rc != 0) {
+ gnutls_assert();
gcry_sexp_release(s_pkey);
+ gcry_sexp_release(s_hash);
+ return GNUTLS_E_INTERNAL_ERROR;
+ }
- if (rc != 0) {
- gnutls_assert();
- return GNUTLS_E_PK_SIG_VERIFY_FAILED;
- }
+ rc = gcry_pk_verify(s_sig, s_hash, s_pkey);
+
+ gcry_sexp_release(s_sig);
+ gcry_sexp_release(s_hash);
+ gcry_sexp_release(s_pkey);
+
+ if (rc != 0) {
+ gnutls_assert();
+ return GNUTLS_E_PK_SIG_VERIFY_FAILED;
+ }
- return 0;
+ return 0;
}