tls: add a hard-coded client_hello message
[siplcs.git] / src / core / sipe-crypt-nss.c
blobc2f933d22b57551552b264e75f63149323001658
1 /**
2 * @file sipe-crypt-nss.c
4 * pidgin-sipe
6 * Copyright (C) 2011 SIPE Project <http://sipe.sourceforge.net/>
7 * Copyright (C) 2010 pier11 <pier11@operamail.com>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 /**
25 * Cypher routines implementation based on NSS.
26 * Includes: RC4, DES
29 #include "glib.h"
31 #include "nss.h"
32 #include "pk11pub.h"
34 #include "sipe-common.h"
35 #include "sipe-backend.h"
36 #include "sipe-crypt.h"
38 /* NSS specific initialization/shutdown */
39 void sipe_crypto_init(SIPE_UNUSED_PARAMETER gboolean production_mode)
41 if (!NSS_IsInitialized()) {
43 * I have a bad feeling about this: according to the NSS
44 * documentation, NSS can only be initialized once.
45 * Unfortunately there seems to be no way to initialize a
46 * "NSS context" that could then be used by the SIPE code
47 * to avoid colliding with other NSS users.
49 * This seems to work, so it'll have to do for now.
51 * It might also be required to move this to the backend
52 * so that the backend code can decide when it is OK to
53 * initialize NSS.
55 NSS_NoDB_Init(".");
56 SIPE_DEBUG_INFO_NOFORMAT("NSS initialised");
60 void sipe_crypto_shutdown(void)
62 /* do nothing for NSS.
63 * We don't want accedently switch off NSS possibly used by other plugin -
64 * ssl-nss in Pidgin for example.
68 /* PRIVATE methods */
70 static PK11Context*
71 sipe_crypt_ctx_create(CK_MECHANISM_TYPE cipherMech, const guchar *key, gsize key_length)
73 PK11SlotInfo* slot;
74 SECItem keyItem;
75 SECItem ivItem;
76 PK11SymKey* SymKey;
77 SECItem *SecParam;
78 PK11Context* EncContext;
80 /* For key */
81 slot = PK11_GetBestSlot(cipherMech, NULL);
83 keyItem.type = siBuffer;
84 keyItem.data = (unsigned char *)key;
85 keyItem.len = key_length;
87 SymKey = PK11_ImportSymKey(slot, cipherMech, PK11_OriginUnwrap, CKA_ENCRYPT, &keyItem, NULL);
89 /* Parameter for crypto context */
90 ivItem.type = siBuffer;
91 ivItem.data = NULL;
92 ivItem.len = 0;
93 SecParam = PK11_ParamFromIV(cipherMech, &ivItem);
95 EncContext = PK11_CreateContextBySymKey(cipherMech, CKA_ENCRYPT, SymKey, SecParam);
97 PK11_FreeSymKey(SymKey);
98 SECITEM_FreeItem(SecParam, PR_TRUE);
99 PK11_FreeSlot(slot);
101 return EncContext;
104 static void
105 sipe_crypt_ctx_encrypt(PK11Context* EncContext, const guchar *in, gsize length, guchar *out)
107 int tmp1_outlen;
109 PK11_CipherOp(EncContext, out, &tmp1_outlen, length, (unsigned char *)in, length);
112 static void
113 sipe_crypt_ctx_destroy(PK11Context* EncContext)
115 PK11_DestroyContext(EncContext, PR_TRUE);
118 static void
119 sipe_crypt(CK_MECHANISM_TYPE cipherMech,
120 const guchar *key, gsize key_length,
121 const guchar *plaintext, gsize plaintext_length,
122 guchar *encrypted_text)
124 void *EncContext;
126 EncContext = sipe_crypt_ctx_create(cipherMech, key, key_length);
127 sipe_crypt_ctx_encrypt(EncContext, plaintext, plaintext_length, encrypted_text);
128 sipe_crypt_ctx_destroy(EncContext);
132 /* PUBLIC methods */
134 void
135 sipe_crypt_des(const guchar *key,
136 const guchar *plaintext, gsize plaintext_length,
137 guchar *encrypted_text)
139 sipe_crypt(CKM_DES_ECB, key, 8, plaintext, plaintext_length, encrypted_text);
142 void
143 sipe_crypt_rc4(const guchar *key, gsize key_length,
144 const guchar *plaintext, gsize plaintext_length,
145 guchar *encrypted_text)
147 sipe_crypt(CKM_RC4, key, key_length, plaintext, plaintext_length, encrypted_text);
150 /* Stream RC4 cipher for file transfer */
151 gpointer
152 sipe_crypt_ft_start(const guchar *key)
154 return sipe_crypt_ctx_create(CKM_RC4, key, 16);
157 void
158 sipe_crypt_ft_stream(gpointer context,
159 const guchar *in, gsize length,
160 guchar *out)
162 sipe_crypt_ctx_encrypt(context, in, length, out);
165 void
166 sipe_crypt_ft_destroy(gpointer context)
168 sipe_crypt_ctx_destroy(context);
172 Local Variables:
173 mode: c
174 c-file-style: "bsd"
175 indent-tabs-mode: t
176 tab-width: 8
177 End: