Line data Source code
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 <openssl/rand.h>
21 : #include <openssl/bio.h>
22 : #include <openssl/pem.h>
23 : #include <openssl/err.h>
24 :
25 : /**
26 : * \ingroup libtds
27 : * \defgroup auth Authentication
28 : * Functions for handling authentication.
29 : */
30 :
31 : /**
32 : * \addtogroup auth
33 : * @{
34 : */
35 :
36 : #ifndef HAVE_OPENSSL
37 : #error HAVE_OPENSSL not defines, this file should not be included
38 : #endif
39 :
40 : static inline const BIGNUM*
41 : rsa_get_n(const RSA *rsa)
42 : {
43 : #if HAVE_RSA_GET0_KEY
44 : const BIGNUM *n, *e, *d;
45 0 : RSA_get0_key(rsa, &n, &e, &d);
46 0 : return n;
47 : #else
48 : return rsa->n;
49 : #endif
50 : }
51 :
52 : static void*
53 0 : tds5_rsa_encrypt(const void *key, size_t key_len, const void *nonce, size_t nonce_len, const char *pwd, size_t *em_size)
54 : {
55 0 : RSA *rsa = NULL;
56 : BIO *keybio;
57 :
58 0 : uint8_t *message = NULL;
59 : size_t message_len, pwd_len;
60 0 : uint8_t *em = NULL;
61 :
62 : int result;
63 :
64 0 : keybio = BIO_new_mem_buf((void*) key, key_len);
65 0 : if (keybio == NULL)
66 : goto error;
67 :
68 0 : rsa = PEM_read_bio_RSAPublicKey(keybio, &rsa, NULL, NULL);
69 0 : if (!rsa)
70 : goto error;
71 :
72 0 : pwd_len = strlen(pwd);
73 0 : message_len = nonce_len + pwd_len;
74 0 : message = tds_new(uint8_t, message_len);
75 0 : if (!message)
76 : goto error;
77 0 : memcpy(message, nonce, nonce_len);
78 0 : memcpy(message + nonce_len, pwd, pwd_len);
79 :
80 0 : em = tds_new(uint8_t, BN_num_bytes(rsa_get_n(rsa)));
81 0 : if (!em)
82 : goto error;
83 :
84 0 : result = RSA_public_encrypt(message_len, message, em, rsa, RSA_PKCS1_OAEP_PADDING);
85 0 : if (result < 0)
86 : goto error;
87 :
88 0 : free(message);
89 0 : RSA_free(rsa);
90 0 : BIO_free(keybio);
91 :
92 0 : *em_size = result;
93 0 : return em;
94 :
95 0 : error:
96 0 : free(message);
97 0 : free(em);
98 0 : RSA_free(rsa);
99 0 : BIO_free(keybio);
100 0 : return NULL;
101 : }
102 :
103 : /** @} */
104 :
|