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) 
   31 #  include <libtasn1.h> 
   35 #  include <nettle/asn1.h> 
   36 #  include <nettle/rsa.h> 
   37 #  include <nettle/bignum.h> 
   52 #error HAVE_GNUTLS not defines, this file should not be included 
   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) 
   75 typedef void nettle_random_func(
void *ctx, 
size_t len, uint8_t *out);
 
   78 nettle_mpz_set_str_256_u(
mpz_t x, 
unsigned length, 
const uint8_t *s)
 
   80     gcry_mpi_scan(&x->num, GCRYMPI_FMT_USG, s, length, NULL);
 
   84 nettle_mpz_get_str_256(
unsigned length, uint8_t *s, 
const mpz_t x)
 
   86     gcry_mpi_print(GCRYMPI_FMT_USG, s, length, NULL, x->num);
 
   90     const unsigned char *data, *data_end;
 
   95 enum asn1_iterator_result {
 
   97     ASN1_ITERATOR_PRIMITIVE,
 
   98     ASN1_ITERATOR_CONSTRUCTED,
 
  103     ASN1_SEQUENCE = ASN1_TAG_SEQUENCE,
 
  106 static enum asn1_iterator_result
 
  114     if (asn1_get_tag_der(der->data, der->data_end - der->data, &cls, &len, &tag) != ASN1_SUCCESS)
 
  115         return ASN1_ITERATOR_ERROR;
 
  118     l = asn1_get_length_der(der->data, der->data_end - der->data, &len);
 
  120         return ASN1_ITERATOR_ERROR;
 
  123     if (cls == ASN1_CLASS_STRUCTURED)
 
  124         return ASN1_ITERATOR_CONSTRUCTED;
 
  125     return ASN1_ITERATOR_PRIMITIVE;
 
  128 static enum asn1_iterator_result
 
  129 asn1_der_iterator_first(
struct asn1_der_iterator *der, 
int size, 
const void *der_buf)
 
  131     der->data = (
const unsigned char *) der_buf;
 
  132     der->data_end = der->data + size;
 
  134     return asn1_der_iterator_next(der);
 
  160     enum asn1_iterator_result ret;
 
  162     ret = asn1_der_iterator_next(der);
 
  163     if (ret != ASN1_ITERATOR_PRIMITIVE || der->type != ASN1_TAG_INTEGER)
 
  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;
 
  169     ret = asn1_der_iterator_next(der);
 
  170     if (ret != ASN1_ITERATOR_PRIMITIVE || der->type != ASN1_TAG_INTEGER)
 
  172     gcry_mpi_scan(&key->e->num, GCRYMPI_FMT_USG, der->data, der->length, NULL);
 
  178 sha1(uint8_t *hash, 
const void *data, 
size_t len)
 
  180     gcry_md_hash_buffer(GCRY_MD_SHA1, hash, data, len);
 
  184 sha1(uint8_t *hash, 
const void *data, 
size_t len)
 
  188     sha1_update(&ctx, len, (
const uint8_t *) data);
 
  189     sha1_digest(&ctx, 20, hash);
 
  195 rnd_func(
void *ctx, 
size_t len, uint8_t * out)
 
  197     tds_random_buffer(out, len);
 
  200 #define dumpl(b,l) tdsdump_dump_buf(TDS_DBG_INFO1, #b, b, l) 
  202 #define dumpl(b,l) do {} while(0) 
  204 #define dump(b) dumpl(b, sizeof(b)) 
  207 #define hash_func sha1 
  208 enum { hash_len = 20  };    
 
  209 enum { key_size_max = 1024 };   
 
  210 static const char label[] = 
"";
 
  213 memxor(uint8_t *dest, 
const uint8_t *src, 
size_t len)
 
  216     for (n = 0; n < len; ++n)
 
  217         dest[n] = dest[n] ^ src[n];
 
  221 mgf_mask(uint8_t *dest, 
size_t dest_len, 
const uint8_t *mask, 
size_t mask_len)
 
  224     uint8_t hash[hash_len];
 
  225     uint8_t seed[mask_len + 4];
 
  227     memcpy(seed, mask, mask_len);
 
  230         TDS_PUT_UA4BE(seed+mask_len, n);
 
  232         hash_func(hash, seed, 
sizeof(seed));
 
  233         if (dest_len <= hash_len) {
 
  234             memxor(dest, hash, dest_len);
 
  238         memxor(dest, hash, hash_len);
 
  240         dest_len -= hash_len;
 
  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)
 
  252         uint8_t ros[hash_len];
 
  253         uint8_t db[key_size_max - hash_len - 1];
 
  255     const unsigned db_len = key_size - hash_len - 1;
 
  257     if (length + hash_len * 2 + 2 > key_size)
 
  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);
 
  269     random(random_ctx, hash_len, em.ros);
 
  273     mgf_mask(em.db, db_len, em.ros, hash_len);
 
  274     dumpl(em.db, db_len);
 
  277     mgf_mask(em.ros, hash_len, em.db, db_len);
 
  280     nettle_mpz_set_str_256_u(m, key_size, em.all);
 
  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)
 
  289     if (!oaep_encrypt(key->size, random_ctx, random, length, message, gibberish))
 
  292     mpz_powm(gibberish, gibberish, key->e, key->n);
 
  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)
 
  301     gnutls_datum_t pubkey_datum = { (
unsigned char *) key, key_len };
 
  305     size_t message_len, pwd_len;
 
  307     unsigned char der_buf[2048];
 
  308     size_t size = 
sizeof(der_buf);
 
  311     rsa_public_key_init(&pubkey);
 
  313     pwd_len = strlen(pwd);
 
  314     message_len = nonce_len + pwd_len;
 
  315     message = tds_new(uint8_t, message_len);
 
  318     memcpy(message, nonce, nonce_len);
 
  319     memcpy(message + nonce_len, pwd, pwd_len);
 
  323     ret = gnutls_pem_base64_decode(
"RSA PUBLIC KEY", &pubkey_datum, der_buf, &size);
 
  325         tdsdump_log(TDS_DBG_ERROR, 
"Error %d decoding public key: %s\n", ret, gnutls_strerror(ret));
 
  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");
 
  336     ret = rsa_public_key_from_der_iterator(&pubkey, key_size_max * 8, &der);
 
  338         tdsdump_log(TDS_DBG_ERROR, 
"Invalid DER content\n");
 
  343     ret = rsa_encrypt_oaep(&pubkey, NULL, rnd_func, message_len, message, p);
 
  345         tdsdump_log(TDS_DBG_ERROR, 
"Error encrypting message\n");
 
  349     em = tds_new(uint8_t, pubkey.size);
 
  350     *em_size = pubkey.size;
 
  354     nettle_mpz_get_str_256(pubkey.size, em, p);
 
  360     rsa_public_key_clear(&pubkey);
 
  
unsigned char tds_peek(TDSSOCKET *tds)
Reads a byte from the TDS stream without removing it.
Definition: read.c:100
void tds_unget_byte(TDSSOCKET *tds)
Unget will always work as long as you don't call it twice in a row.
Definition: read.c:89
TDSRET tds_get_char_data(TDSSOCKET *tds, char *row_buffer, size_t wire_size, TDSCOLUMN *curcol)
Fetch character data the wire.
Definition: read.c:195
unsigned pkt_pos
position in pkt
Definition: tds.h:1572
DSTR * tds_dstr_alloc(DSTR *s, size_t length)
allocate space for length char
Definition: tdsstring.c:165
unsigned size_len
length size (0, 1, 2 or 4)
Definition: tds.h:1574
TDSPACKET * frozen_packets
list of packets frozen, points to first one.
Definition: tds.h:1204
Definition: sec_negotiate_gnutls.h:59
unsigned char * in_buf
Input buffer.
Definition: tds.h:1178
TDSRET tds_convert_stream(TDSSOCKET *tds, TDSICONV *char_conv, TDS_ICONV_DIRECTION direction, TDSINSTREAM *istream, TDSOUTSTREAM *ostream)
Reads and writes from a stream converting characters.
Definition: stream.c:71
int tds_read_packet(TDSSOCKET *tds)
Read in one 'packet' from the server.
Definition: packet.c:527
Information about blobs (e.g.
Definition: tds.h:594
void tds_freeze(TDSSOCKET *tds, TDSFREEZE *freeze, unsigned size_len)
Stop writing to server and cache every packet not sending them to server.
Definition: packet.c:907
TDSPACKET * send_packet
packet we are preparing to send
Definition: tds.h:1232
TDSLOGIN * login
config for login stuff.
Definition: tds.h:1259
TDS 7.2 SMP packet header.
Definition: proto.h:361
Definition: sec_negotiate_gnutls.h:137
Hold information for any results.
Definition: tds.h:770
static char * tds_dstr_buf(DSTR *s)
Returns a buffer to edit the string.
Definition: string.h:71
unsigned char * out_buf
Output buffer.
Definition: tds.h:1186
void tdsdump_dump_buf(const char *file, unsigned int level_line, const char *msg, const void *buf, size_t length)
Dump the contents of data into the log file in a human readable format.
Definition: log.c:256
TDSENV env
environment is shared between all sessions
Definition: tds.h:1102
Information for a server connection.
Definition: tds.h:1164
const int tds_numeric_bytes_per_prec[]
The following little table is indexed by precision and will tell us the number of bytes required to s...
Definition: numeric.c:41
TDS_UINT tds_get_uint(TDSSOCKET *tds)
Get an int32 from the server.
Definition: read.c:127
TDSRET tds_freeze_abort(TDSFREEZE *freeze)
Discard all data written after the freeze.
Definition: packet.c:961
void tds_staticout_stream_init(TDSSTATICOUTSTREAM *stream, void *ptr, size_t len)
Initialize an output stream for write into a static allocated buffer.
Definition: stream.c:313
unsigned char tds_get_byte(TDSSOCKET *tds)
Return a single byte from the input buffer.
Definition: read.c:72
TDSPACKET * pkt
first packet frozen
Definition: tds.h:1570
bool tds_get_n(TDSSOCKET *tds, void *dest, size_t need)
Get N bytes from the buffer and return them in the already allocated space   given to us.
Definition: read.c:230
#define tds_put_tinyint(tds, ti)
Output a tinyint value.
Definition: tds.h:1468
void tdsdump_log(const char *file, unsigned int level_line, const char *fmt,...)
Write a message to the debug log.
Definition: log.c:354
TDS_INT column_size
maximun size of data.
Definition: tds.h:695
DSTR * tds_dstr_get(TDSSOCKET *tds, DSTR *s, size_t len)
Reads a string from wire and put in a DSTR.
Definition: read.c:293
Definition: sec_negotiate_gnutls.h:89
void tds_close_socket(TDSSOCKET *tds)
Close current socket.
Definition: net.c:548
int block_size
packet size (512-65535)
Definition: tds.h:966
void tds_datain_stream_init(TDSDATAINSTREAM *stream, TDSSOCKET *tds, size_t wire_size)
Initialize a data input stream.
Definition: stream.c:204
output stream to write data to a static buffer.
Definition: stream.h:92
static const char * tds_dstr_cstr(const DSTR *s)
Returns a C version (NUL terminated string) of dstr.
Definition: string.h:78
volatile unsigned char in_cancel
indicate we are waiting a cancel reply; discard tokens till acknowledge; 1 mean we have to send cance...
Definition: tds.h:1249
size_t tds_get_string(TDSSOCKET *tds, size_t string_len, char *dest, size_t dest_size)
Fetch a string from the wire.
Definition: read.c:166
TDS_UINT8 tds_get_uint8(TDSSOCKET *tds)
Get an uint64 from the server.
Definition: read.c:140
size_t wire_size
bytes still to read
Definition: stream.h:65
TDSRET tds_freeze_close_len(TDSFREEZE *freeze, int32_t size)
Stop keeping data for this specific freeze.
Definition: packet.c:1031
unsigned data_len
data length, this does not account SMP header, only TDS part
Definition: tds.h:1072
TDS_STATE tds_set_state(TDSSOCKET *tds, TDS_STATE state)
Set state of TDS connection, with logging and checking.
Definition: util.c:58
unsigned char out_flag
output buffer type
Definition: tds.h:1197
int tds_select(TDSSOCKET *tds, unsigned tds_sel, int timeout_seconds)
Select on a socket until it's available or the timeout expires.
Definition: net.c:612
TDSRET tds_freeze_close(TDSFREEZE *freeze)
Stop keeping data for this specific freeze.
Definition: packet.c:996
unsigned out_pos
current position in out_buf
Definition: tds.h:1194
TDS_INT column_cur_size
size written in variable (ie: char, text, binary).
Definition: tds.h:737
Structure to hold a string.
Definition: string.h:36
TDSICONV * char_conv
refers to previously allocated iconv information
Definition: tds.h:713
int tdserror(const TDSCONTEXT *tds_ctx, TDSSOCKET *tds, int msgno, int errnum)
Call the client library's error handler (for library-generated errors only)
Definition: util.c:321
input stream to read data from tds protocol
Definition: stream.h:63
unsigned in_len
input buffer length
Definition: tds.h:1195
size_t tds_freeze_written(TDSFREEZE *freeze)
Compute how many bytes has been written from freeze.
Definition: packet.c:935
TDSSOCKET * tds
which socket we refer to
Definition: tds.h:1568
DSTR password
password of account login
Definition: tds.h:536
TDS_USMALLINT tds_get_usmallint(TDSSOCKET *tds)
Get an int16 from the server.
Definition: read.c:113
Provide poll call where missing.
unsigned int out_buf_max
Maximum size of packet pointed by out_buf.
Definition: tds.h:1192
Metadata about columns in regular and compute rows.
Definition: tds.h:690
@ TDS_DEAD
no connection
Definition: tds.h:796
TDSRET tds_flush_packet(TDSSOCKET *tds)
Flush packet to server.
Definition: write.c:224
TDS_SERVER_TYPE column_type
This type can be different from wire type because conversion (e.g.
Definition: tds.h:697
unsigned char in_flag
input buffer type
Definition: tds.h:1196
DSTR * tds_dstr_setlen(DSTR *s, size_t length)
limit length of string, MUST be <= current length
Definition: tdsstring.c:145
char * buffer
write buffer.
Definition: stream.h:50
unsigned in_pos
current position in in_buf
Definition: tds.h:1193
static size_t read_and_convert(TDSSOCKET *tds, TDSICONV *char_conv, size_t *wire_size, char *outbuf, size_t outbytesleft)
For UTF-8 and similar, tds_iconv() may encounter a partial sequence when the chunk boundary is not al...
Definition: read.c:269
TDS_INT tds_numeric_to_string(const TDS_NUMERIC *numeric, char *s)
Definition: numeric.c:95