tls: add Server Key Exchange message
[siplcs.git] / src / core / sipe-crypt-openssl.c
blob3c94be9d79bd8f9ad39bae917706ed3c57baed9f
1 /**
2 * @file sipe-crypt-openssl.c
4 * pidgin-sipe
6 * Copyright (C) 2013-2015 SIPE Project <http://sipe.sourceforge.net/>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 /**
24 * Cipher routines implementation based on OpenSSL.
26 #include <openssl/evp.h>
27 #include <openssl/rsa.h>
29 #include "glib.h"
31 #include "sipe-common.h"
32 #include "sipe-backend.h"
33 #include "sipe-crypt.h"
35 /* OpenSSL specific initialization/shutdown */
36 void sipe_crypto_init(SIPE_UNUSED_PARAMETER gboolean production_mode)
38 /* nothing to do here */
41 void sipe_crypto_shutdown(void)
43 /* nothing to do here */
46 static void openssl_oneshot_crypt(const EVP_CIPHER *type,
47 const guchar *key, gsize key_length,
48 const guchar *plaintext, gsize plaintext_length,
49 guchar *encrypted_text)
51 EVP_CIPHER_CTX ctx;
52 int encrypted_length = 0;
54 /* initialize context */
55 EVP_CIPHER_CTX_init(&ctx);
56 EVP_EncryptInit_ex(&ctx, type, NULL, key, NULL);
58 /* set encryption parameters */
59 if (key_length)
60 EVP_CIPHER_CTX_set_key_length(&ctx, key_length);
61 EVP_EncryptInit_ex(&ctx, NULL, NULL, key, NULL);
63 /* encrypt */
64 EVP_EncryptUpdate(&ctx,
65 encrypted_text, &encrypted_length,
66 plaintext, plaintext_length);
67 encrypted_text += encrypted_length;
68 EVP_EncryptFinal_ex(&ctx, encrypted_text, &encrypted_length);
70 /* cleanup */
71 EVP_CIPHER_CTX_cleanup(&ctx);
74 /* DES CBC with 56-bit key */
75 void sipe_crypt_des(const guchar *key,
76 const guchar *plaintext, gsize plaintext_length,
77 guchar *encrypted_text)
79 openssl_oneshot_crypt(EVP_des_cbc(),
80 key, 0 /* fixed length */,
81 plaintext, plaintext_length,
82 encrypted_text);
85 /* RC4 with variable length key */
86 void sipe_crypt_rc4(const guchar *key, gsize key_length,
87 const guchar *plaintext, gsize plaintext_length,
88 guchar *encrypted_text)
90 openssl_oneshot_crypt(EVP_rc4(),
91 key, key_length,
92 plaintext, plaintext_length,
93 encrypted_text);
96 gboolean sipe_crypt_rsa_encrypt(gpointer public,
97 gsize modulus_length,
98 const guchar *plaintext,
99 guchar *encrypted_text)
101 return(RSA_public_encrypt(modulus_length,
102 plaintext,
103 encrypted_text,
104 public,
105 RSA_NO_PADDING)
106 != -1);
109 gboolean sipe_crypt_rsa_decrypt(gpointer private,
110 gsize modulus_length,
111 const guchar *encrypted_text,
112 guchar *plaintext)
114 return(RSA_private_decrypt(modulus_length,
115 encrypted_text,
116 plaintext,
117 private,
118 RSA_NO_PADDING)
119 != -1);
122 guchar *sipe_crypt_rsa_sign(gpointer private,
123 const guchar *digest, gsize digest_length,
124 gsize *signature_length)
126 guchar *signature = g_malloc(RSA_size(private));
127 unsigned int length;
129 if (!RSA_sign(NID_md5_sha1,
130 digest, digest_length,
131 signature, &length,
132 private)) {
133 g_free(signature);
134 return(NULL);
137 *signature_length = length;
138 return(signature);
141 gboolean sipe_crypt_verify_rsa(gpointer public,
142 const guchar *digest, gsize digest_length,
143 const guchar *signature, gsize signature_length)
145 return(RSA_verify(NID_md5_sha1,
146 digest, digest_length,
147 /* older OpenSSL version don't have "const" here */
148 (guchar *) signature, signature_length,
149 public));
152 static gpointer openssl_EVP_init(const EVP_CIPHER *(*evp)(),
153 const guchar *key,
154 gsize key_length)
156 EVP_CIPHER_CTX *ctx = g_malloc(sizeof(EVP_CIPHER_CTX));
158 /* initialize context */
159 EVP_CIPHER_CTX_init(ctx);
160 EVP_EncryptInit_ex(ctx, (*evp)(), NULL, key, NULL);
162 /* set encryption parameters */
163 EVP_CIPHER_CTX_set_key_length(ctx, key_length);
164 EVP_EncryptInit_ex(ctx, NULL, NULL, key, NULL);
166 return(ctx);
169 /* Stream RC4 cipher for file transfer with fixed-length 128-bit key */
170 gpointer sipe_crypt_ft_start(const guchar *key)
172 return(openssl_EVP_init(EVP_rc4, key, 16));
175 void sipe_crypt_ft_stream(gpointer context,
176 const guchar *in, gsize length,
177 guchar *out)
179 int tmp;
180 EVP_EncryptUpdate(context, out, &tmp, in, length);
183 void sipe_crypt_ft_destroy(gpointer context)
185 EVP_CIPHER_CTX_cleanup(context);
186 g_free(context);
189 /* Stream cipher for TLS with variable key length */
190 gpointer sipe_crypt_tls_start(guint type, const guchar *key, gsize key_length)
192 gpointer result = NULL;
194 switch (type) {
195 case SIPE_CRYPT_STREAM_RC4:
196 result = openssl_EVP_init(EVP_rc4, key, key_length);
197 break;
199 case SIPE_CRYPT_STREAM_AES_CBC:
200 switch (key_length) {
201 case 16:
202 result = openssl_EVP_init(EVP_aes_128_cbc, key, key_length);
203 break;
204 case 24:
205 result = openssl_EVP_init(EVP_aes_192_cbc, key, key_length);
206 break;
207 case 32:
208 result = openssl_EVP_init(EVP_aes_256_cbc, key, key_length);
209 break;
210 default:
211 SIPE_DEBUG_ERROR("sipe_crypt_tls_start: unsupported key length %" G_GSIZE_FORMAT " bytes for AES CBC",
212 key_length);
213 break;
215 break;
217 default:
218 SIPE_DEBUG_ERROR("sipe_crypt_tls_start: unknown cipher type '%d'",
219 type);
220 break;
223 return(result);
226 void sipe_crypt_tls_stream(gpointer context,
227 const guchar *in, gsize length,
228 guchar *out)
230 int tmp;
231 EVP_EncryptUpdate(context, out, &tmp, in, length);
234 void sipe_crypt_tls_destroy(gpointer context)
236 EVP_CIPHER_CTX_cleanup(context);
237 g_free(context);
241 Local Variables:
242 mode: c
243 c-file-style: "bsd"
244 indent-tabs-mode: t
245 tab-width: 8
246 End: