1 /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
2  * Copyright (C) 2015  Frediano Ziglio
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19 
20 #include <gnutls/gnutls.h>
21 #include <gnutls/crypto.h>
22 #ifdef HAVE_GNUTLS_ABSTRACT_H
23 #  include <gnutls/abstract.h>
24 #endif
25 
26 #if !defined(HAVE_NETTLE) || !defined(HAVE_GMP) || !defined(HAVE_GNUTLS_RND)
27 #  include <gcrypt.h>
28 #endif
29 
30 #ifndef HAVE_NETTLE
31 #  include <libtasn1.h>
32 #endif
33 
34 #ifdef HAVE_NETTLE
35 #  include <nettle/asn1.h>
36 #  include <nettle/rsa.h>
37 #  include <nettle/bignum.h>
38 #endif
39 
40 /**
41  * \ingroup libtds
42  * \defgroup auth Authentication
43  * Functions for handling authentication.
44  */
45 
46 /**
47  * \addtogroup auth
48  * @{
49  */
50 
51 #ifndef HAVE_GNUTLS
52 #error HAVE_GNUTLS not defines, this file should not be included
53 #endif
54 
55 /* emulate GMP if not present */
56 #ifndef HAVE_GMP
57 #define HAVE_GMP 1
58 
59 typedef struct {
60 	gcry_mpi_t num;
61 } mpz_t[1];
62 
63 #define mpz_powm(w,n,e,m) \
64 	gcry_mpi_powm((w)->num, (n)->num, (e)->num, (m)->num);
65 #define mpz_init(n) do { (n)->num = NULL; } while(0)
66 #define mpz_clear(n) gcry_mpi_release((n)->num)
67 
68 #endif
69 
70 
71 /* emulate Nettle is not present */
72 #ifndef HAVE_NETTLE
73 #define HAVE_NETTLE 1
74 
75 typedef void nettle_random_func(void *ctx, size_t len, uint8_t *out);
76 
77 static inline void
nettle_mpz_set_str_256_u(mpz_t x,unsigned length,const uint8_t * s)78 nettle_mpz_set_str_256_u(mpz_t x, unsigned length, const uint8_t *s)
79 {
80 	gcry_mpi_scan(&x->num, GCRYMPI_FMT_USG, s, length, NULL);
81 }
82 
83 static inline void
nettle_mpz_get_str_256(unsigned length,uint8_t * s,const mpz_t x)84 nettle_mpz_get_str_256(unsigned length, uint8_t *s, const mpz_t x)
85 {
86 	gcry_mpi_print(GCRYMPI_FMT_USG, s, length, NULL, x->num);
87 }
88 
89 struct asn1_der_iterator {
90 	const unsigned char *data, *data_end;
91 	unsigned long length;
92 	unsigned long type;
93 };
94 
95 enum asn1_iterator_result {
96 	ASN1_ITERATOR_ERROR,
97 	ASN1_ITERATOR_PRIMITIVE,
98 	ASN1_ITERATOR_CONSTRUCTED,
99 	ASN1_ITERATOR_END,
100 };
101 
102 enum {
103 	ASN1_SEQUENCE = ASN1_TAG_SEQUENCE,
104 };
105 
106 static enum asn1_iterator_result
asn1_der_iterator_next(struct asn1_der_iterator * der)107 asn1_der_iterator_next(struct asn1_der_iterator *der)
108 {
109 	unsigned char cls;
110 	unsigned long tag;
111 	int len;
112 	long l;
113 
114 	if (asn1_get_tag_der(der->data, der->data_end - der->data, &cls, &len, &tag) != ASN1_SUCCESS)
115 		return ASN1_ITERATOR_ERROR;
116 	der->type = tag;
117 	der->data += len;
118 	l = asn1_get_length_der(der->data, der->data_end - der->data, &len);
119 	if (l < 0)
120 		return ASN1_ITERATOR_ERROR;
121 	der->data += len;
122 	der->length = l;
123 	if (cls == ASN1_CLASS_STRUCTURED)
124 		return ASN1_ITERATOR_CONSTRUCTED;
125 	return ASN1_ITERATOR_PRIMITIVE;
126 }
127 
128 static enum asn1_iterator_result
asn1_der_iterator_first(struct asn1_der_iterator * der,int size,const void * der_buf)129 asn1_der_iterator_first(struct asn1_der_iterator *der, int size, const void *der_buf)
130 {
131 	der->data = (const unsigned char *) der_buf;
132 	der->data_end = der->data + size;
133 
134 	return asn1_der_iterator_next(der);
135 }
136 
137 struct rsa_public_key {
138 	unsigned size;
139 	mpz_t n, e;
140 };
141 
142 static void
rsa_public_key_init(struct rsa_public_key * key)143 rsa_public_key_init(struct rsa_public_key *key)
144 {
145 	key->size = 0;
146 	mpz_init(key->n);
147 	mpz_init(key->e);
148 }
149 
150 static void
rsa_public_key_clear(struct rsa_public_key * key)151 rsa_public_key_clear(struct rsa_public_key *key)
152 {
153 	mpz_clear(key->n);
154 	mpz_clear(key->e);
155 }
156 
157 static int
rsa_public_key_from_der_iterator(struct rsa_public_key * key,unsigned key_bits,struct asn1_der_iterator * der)158 rsa_public_key_from_der_iterator(struct rsa_public_key *key, unsigned key_bits, struct asn1_der_iterator *der)
159 {
160 	enum asn1_iterator_result ret;
161 
162 	ret = asn1_der_iterator_next(der);
163 	if (ret != ASN1_ITERATOR_PRIMITIVE || der->type != ASN1_TAG_INTEGER)
164 		return 0;
165 	gcry_mpi_scan(&key->n->num, GCRYMPI_FMT_USG, der->data, der->length, NULL);
166 	key->size = (gcry_mpi_get_nbits(key->n->num)+7)/8;
167 	der->data += der->length;
168 
169 	ret = asn1_der_iterator_next(der);
170 	if (ret != ASN1_ITERATOR_PRIMITIVE || der->type != ASN1_TAG_INTEGER)
171 		return 0;
172 	gcry_mpi_scan(&key->e->num, GCRYMPI_FMT_USG, der->data, der->length, NULL);
173 
174 	return 1;
175 }
176 
177 static void
sha1(uint8_t * hash,const void * data,size_t len)178 sha1(uint8_t *hash, const void *data, size_t len)
179 {
180 	gcry_md_hash_buffer(GCRY_MD_SHA1, hash, data, len);
181 }
182 #else
183 static void
sha1(uint8_t * hash,const void * data,size_t len)184 sha1(uint8_t *hash, const void *data, size_t len)
185 {
186 	struct sha1_ctx ctx;
187 	sha1_init(&ctx);
188 	sha1_update(&ctx, len, (const uint8_t *) data);
189 	sha1_digest(&ctx, 20, hash);
190 }
191 #endif
192 
193 
194 static void
rnd_func(void * ctx,size_t len,uint8_t * out)195 rnd_func(void *ctx, size_t len, uint8_t * out)
196 {
197 	tds_random_buffer(out, len);
198 }
199 
200 #define dumpl(b,l) tdsdump_dump_buf(TDS_DBG_INFO1, #b, b, l)
201 #ifndef dumpl
202 #define dumpl(b,l) do {} while(0)
203 #endif
204 #define dump(b) dumpl(b, sizeof(b))
205 
206 /* OAEP configuration parameters */
207 #define hash_func sha1
208 enum { hash_len = 20  };	/* sha1 length */
209 enum { key_size_max = 1024 };	/* max key in bytes */
210 static const char label[] = "";
211 
212 static void
memxor(uint8_t * dest,const uint8_t * src,size_t len)213 memxor(uint8_t *dest, const uint8_t *src, size_t len)
214 {
215 	size_t n;
216 	for (n = 0; n < len; ++n)
217 		dest[n] = dest[n] ^ src[n];
218 }
219 
220 static void
mgf_mask(uint8_t * dest,size_t dest_len,const uint8_t * mask,size_t mask_len)221 mgf_mask(uint8_t *dest, size_t dest_len, const uint8_t *mask, size_t mask_len)
222 {
223 	unsigned n = 0;
224 	uint8_t hash[hash_len];
225 	uint8_t seed[mask_len + 4];
226 
227 	memcpy(seed, mask, mask_len);
228 	/* we always have some data and check is done internally */
229 	for (;;) {
230 		TDS_PUT_UA4BE(seed+mask_len, n);
231 
232 		hash_func(hash, seed, sizeof(seed));
233 		if (dest_len <= hash_len) {
234 			memxor(dest, hash, dest_len);
235 			break;
236 		}
237 
238 		memxor(dest, hash, hash_len);
239 		dest += hash_len;
240 		dest_len -= hash_len;
241 		++n;
242 	}
243 }
244 
245 static int
oaep_encrypt(size_t key_size,void * random_ctx,nettle_random_func * random,size_t length,const uint8_t * message,mpz_t m)246 oaep_encrypt(size_t key_size, void *random_ctx, nettle_random_func *random,
247 	       size_t length, const uint8_t *message, mpz_t m)
248 {
249 	/* EM: 0x00 ROS (HASH 0x00.. 0x01 message) */
250 	struct {
251 		uint8_t all[1]; /* zero but used to access all data */
252 		uint8_t ros[hash_len];
253 		uint8_t db[key_size_max - hash_len - 1];
254 	} em;
255 	const unsigned db_len = key_size - hash_len - 1;
256 
257 	if (length + hash_len * 2 + 2 > key_size)
258 		/* Message too long for this key. */
259 		return 0;
260 
261 	/* create db */
262 	memset(&em, 0, sizeof(em));
263 	hash_func(em.db, label, strlen(label));
264 	em.all[key_size - length - 1] = 0x1;
265 	memcpy(em.all+(key_size - length), message, length);
266 	dumpl(em.db, db_len);
267 
268 	/* create ros */
269 	random(random_ctx, hash_len, em.ros);
270 	dump(em.ros);
271 
272 	/* mask db */
273 	mgf_mask(em.db, db_len, em.ros, hash_len);
274 	dumpl(em.db, db_len);
275 
276 	/* mask ros */
277 	mgf_mask(em.ros, hash_len, em.db, db_len);
278 	dump(em.ros);
279 
280 	nettle_mpz_set_str_256_u(m, key_size, em.all);
281 
282 	return 1;
283 }
284 
285 static int
rsa_encrypt_oaep(const struct rsa_public_key * key,void * random_ctx,nettle_random_func * random,size_t length,const uint8_t * message,mpz_t gibberish)286 rsa_encrypt_oaep(const struct rsa_public_key *key, void *random_ctx, nettle_random_func *random,
287 	    size_t length, const uint8_t *message, mpz_t gibberish)
288 {
289 	if (!oaep_encrypt(key->size, random_ctx, random, length, message, gibberish))
290 		return 0;
291 
292 	mpz_powm(gibberish, gibberish, key->e, key->n);
293 	return 1;
294 }
295 
296 static void*
tds5_rsa_encrypt(const void * key,size_t key_len,const void * nonce,size_t nonce_len,const char * pwd,size_t * em_size)297 tds5_rsa_encrypt(const void *key, size_t key_len, const void *nonce, size_t nonce_len, const char *pwd, size_t *em_size)
298 {
299 	int ret;
300 	mpz_t p;
301 	gnutls_datum_t pubkey_datum = { (unsigned char *) key, key_len };
302 	struct asn1_der_iterator der;
303 	struct rsa_public_key pubkey;
304 	uint8_t *message;
305 	size_t message_len, pwd_len;
306 	uint8_t *em = NULL;
307 	unsigned char der_buf[2048];
308 	size_t size = sizeof(der_buf);
309 
310 	mpz_init(p);
311 	rsa_public_key_init(&pubkey);
312 
313 	pwd_len = strlen(pwd);
314 	message_len = nonce_len + pwd_len;
315 	message = tds_new(uint8_t, message_len);
316 	if (!message)
317 		return NULL;
318 	memcpy(message, nonce, nonce_len);
319 	memcpy(message + nonce_len, pwd, pwd_len);
320 
321 	/* use nettle directly */
322 	/* parse PEM, get DER */
323 	ret = gnutls_pem_base64_decode("RSA PUBLIC KEY", &pubkey_datum, der_buf, &size);
324 	if (ret) {
325 		tdsdump_log(TDS_DBG_ERROR, "Error %d decoding public key: %s\n", ret, gnutls_strerror(ret));
326 		goto error;
327 	}
328 
329 	/* get key with nettle using DER */
330 	ret = asn1_der_iterator_first(&der, size, der_buf);
331 	if (ret != ASN1_ITERATOR_CONSTRUCTED || der.type != ASN1_SEQUENCE) {
332 		tdsdump_log(TDS_DBG_ERROR, "Invalid DER content\n");
333 		goto error;
334 	}
335 
336 	ret = rsa_public_key_from_der_iterator(&pubkey, key_size_max * 8, &der);
337 	if (!ret) {
338 		tdsdump_log(TDS_DBG_ERROR, "Invalid DER content\n");
339 		goto error;
340 	}
341 
342 	/* get password encrypted */
343 	ret = rsa_encrypt_oaep(&pubkey, NULL, rnd_func, message_len, message, p);
344 	if (!ret) {
345 		tdsdump_log(TDS_DBG_ERROR, "Error encrypting message\n");
346 		goto error;
347 	}
348 
349 	em = tds_new(uint8_t, pubkey.size);
350 	*em_size = pubkey.size;
351 	if (!em)
352 		goto error;
353 
354 	nettle_mpz_get_str_256(pubkey.size, em, p);
355 
356 	tdsdump_dump_buf(TDS_DBG_INFO1, "em", em, pubkey.size);
357 
358 error:
359 	free(message);
360 	rsa_public_key_clear(&pubkey);
361 	mpz_clear(p);
362 	return em;
363 }
364 
365 /** @} */
366 
367