20#include <gnutls/gnutls.h>
21#include <gnutls/crypto.h>
22#ifdef HAVE_GNUTLS_ABSTRACT_H
23# include <gnutls/abstract.h>
26#if !defined(HAVE_NETTLE) || !defined(HAVE_GMP) || !defined(HAVE_GNUTLS_RND)
35# include <nettle/asn1.h>
36# include <nettle/rsa.h>
37# include <nettle/bignum.h>
38# include <nettle/version.h>
53#error HAVE_GNUTLS not defined, this file should not be included
64#define mpz_powm(w,n,e,m) \
65 gcry_mpi_powm((w)->num, (n)->num, (e)->num, (m)->num);
66#define mpz_init(n) do { (n)->num = NULL; } while(0)
67#define mpz_clear(n) gcry_mpi_release((n)->num)
76typedef void nettle_random_func(
void *ctx,
size_t len, uint8_t *out);
79nettle_mpz_set_str_256_u(
mpz_t x,
unsigned length,
const uint8_t *s)
81 gcry_mpi_scan(&x->num, GCRYMPI_FMT_USG, s, length, NULL);
85nettle_mpz_get_str_256(
unsigned length, uint8_t *s,
const mpz_t x)
87 gcry_mpi_print(GCRYMPI_FMT_USG, s, length, NULL, x->num);
91 const unsigned char *data, *data_end;
96enum asn1_iterator_result {
98 ASN1_ITERATOR_PRIMITIVE,
99 ASN1_ITERATOR_CONSTRUCTED,
104 ASN1_SEQUENCE = ASN1_TAG_SEQUENCE,
107static enum asn1_iterator_result
115 if (asn1_get_tag_der(der->data, der->data_end - der->data, &cls, &len, &tag) != ASN1_SUCCESS)
116 return ASN1_ITERATOR_ERROR;
119 l = asn1_get_length_der(der->data, der->data_end - der->data, &len);
121 return ASN1_ITERATOR_ERROR;
124 if (cls == ASN1_CLASS_STRUCTURED)
125 return ASN1_ITERATOR_CONSTRUCTED;
126 return ASN1_ITERATOR_PRIMITIVE;
129static enum asn1_iterator_result
130asn1_der_iterator_first(
struct asn1_der_iterator *der,
int size,
const void *der_buf)
132 der->data = (
const unsigned char *) der_buf;
133 der->data_end = der->data + size;
135 return asn1_der_iterator_next(der);
161 enum asn1_iterator_result ret;
163 ret = asn1_der_iterator_next(der);
164 if (ret != ASN1_ITERATOR_PRIMITIVE || der->type != ASN1_TAG_INTEGER)
166 gcry_mpi_scan(&key->n->num, GCRYMPI_FMT_USG, der->data, der->length, NULL);
167 key->size = (gcry_mpi_get_nbits(key->n->num)+7)/8;
168 der->data += der->length;
170 ret = asn1_der_iterator_next(der);
171 if (ret != ASN1_ITERATOR_PRIMITIVE || der->type != ASN1_TAG_INTEGER)
173 gcry_mpi_scan(&key->e->num, GCRYMPI_FMT_USG, der->data, der->length, NULL);
179sha1(uint8_t *hash,
const void *data,
size_t len)
181 gcry_md_hash_buffer(GCRY_MD_SHA1, hash, data, len);
185sha1(uint8_t *hash,
const void *data,
size_t len)
189 sha1_update(&ctx, len, (
const uint8_t *) data);
190#if defined(NETTLE_VERSION_MAJOR) && NETTLE_VERSION_MAJOR >= 4
191 sha1_digest(&ctx, hash);
193 sha1_digest(&ctx, 20, hash);
199#define dumpl(b,l) tdsdump_dump_buf(TDS_DBG_INFO1, #b, b, l)
201#define dumpl(b,l) do {} while(0)
203#define dump(b) dumpl(b, sizeof(b))
206#define hash_func sha1
207enum { hash_len = 20 };
208enum { key_size_max = 1024 };
209static const char label[] =
"";
212memxor(uint8_t *dest,
const uint8_t *src,
size_t len)
215 for (n = 0; n < len; ++n)
216 dest[n] = dest[n] ^ src[n];
220mgf_mask(uint8_t *dest,
size_t dest_len,
const uint8_t *mask,
size_t mask_len)
223 uint8_t hash[hash_len];
224 uint8_t seed[mask_len + 4];
226 memcpy(seed, mask, mask_len);
229 TDS_PUT_UA4BE(seed+mask_len, n);
231 hash_func(hash, seed,
sizeof(seed));
232 if (dest_len <= hash_len) {
233 memxor(dest, hash, dest_len);
237 memxor(dest, hash, hash_len);
239 dest_len -= hash_len;
245oaep_encrypt(
size_t key_size,
size_t length,
const uint8_t *message,
mpz_t m)
250 uint8_t ros[hash_len];
251 uint8_t db[key_size_max - hash_len - 1];
253 const unsigned db_len = key_size - hash_len - 1;
255 if (length + hash_len * 2 + 2 > key_size)
260 memset(&em, 0,
sizeof(em));
261 hash_func(em.db, label, strlen(label));
262 em.all[key_size - length - 1] = 0x1;
263 memcpy(em.all+(key_size - length), message, length);
264 dumpl(em.db, db_len);
267 tds_random_buffer(em.ros, hash_len);
271 mgf_mask(em.db, db_len, em.ros, hash_len);
272 dumpl(em.db, db_len);
275 mgf_mask(em.ros, hash_len, em.db, db_len);
278 nettle_mpz_set_str_256_u(m, key_size, em.all);
285 size_t length,
const uint8_t *message,
mpz_t gibberish)
287 if (!oaep_encrypt(key->size, length, message, gibberish))
290 mpz_powm(gibberish, gibberish, key->e, key->n);
295tds5_rsa_encrypt(
const void *key,
size_t key_len,
const void *nonce,
size_t nonce_len,
const char *pwd,
size_t *em_size)
299 gnutls_datum_t pubkey_datum = { (
unsigned char *) key, key_len };
303 size_t message_len, pwd_len;
305 unsigned char der_buf[2048];
306 size_t size =
sizeof(der_buf);
309 rsa_public_key_init(&pubkey);
311 pwd_len = strlen(pwd);
312 message_len = nonce_len + pwd_len;
313 message = tds_new(uint8_t, message_len);
316 memcpy(message, nonce, nonce_len);
317 memcpy(message + nonce_len, pwd, pwd_len);
321 ret = gnutls_pem_base64_decode(
"RSA PUBLIC KEY", &pubkey_datum, der_buf, &size);
323 tdsdump_log(TDS_DBG_ERROR,
"Error %d decoding public key: %s\n", ret, gnutls_strerror(ret));
328 ret = asn1_der_iterator_first(&der, size, der_buf);
329 if (ret != ASN1_ITERATOR_CONSTRUCTED || der.type != ASN1_SEQUENCE) {
330 tdsdump_log(TDS_DBG_ERROR,
"Invalid DER content\n");
334 ret = rsa_public_key_from_der_iterator(&pubkey, key_size_max * 8, &der);
336 tdsdump_log(TDS_DBG_ERROR,
"Invalid DER content\n");
341 ret = rsa_encrypt_oaep(&pubkey, message_len, message, p);
343 tdsdump_log(TDS_DBG_ERROR,
"Error encrypting message\n");
347 em = tds_new(uint8_t, pubkey.size);
348 *em_size = pubkey.size;
352 nettle_mpz_get_str_256(pubkey.size, em, p);
354 tdsdump_dump_buf(TDS_DBG_INFO1,
"em", em, pubkey.size);
358 rsa_public_key_clear(&pubkey);
Definition sec_negotiate_gnutls.h:60
Definition sec_negotiate_gnutls.h:90
Definition sec_negotiate_gnutls.h:138