2 * @file sipe-crypt-nss.c
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
25 * Cypher routines implementation based on NSS.
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
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.
71 sipe_crypt_ctx_create(CK_MECHANISM_TYPE cipherMech
, const guchar
*key
, gsize key_length
)
78 PK11Context
* EncContext
;
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
;
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
);
105 sipe_crypt_ctx_encrypt(PK11Context
* EncContext
, const guchar
*in
, gsize length
, guchar
*out
)
109 PK11_CipherOp(EncContext
, out
, &tmp1_outlen
, length
, (unsigned char *)in
, length
);
113 sipe_crypt_ctx_destroy(PK11Context
* EncContext
)
115 PK11_DestroyContext(EncContext
, PR_TRUE
);
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
)
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
);
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
);
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 */
152 sipe_crypt_ft_start(const guchar
*key
)
154 return sipe_crypt_ctx_create(CKM_RC4
, key
, 16);
158 sipe_crypt_ft_stream(gpointer context
,
159 const guchar
*in
, gsize length
,
162 sipe_crypt_ctx_encrypt(context
, in
, length
, out
);
166 sipe_crypt_ft_destroy(gpointer context
)
168 sipe_crypt_ctx_destroy(context
);