i18n: update bug tracker URL in script
[siplcs.git] / src / core / sipe-digest-nss.c
blob1a64541821b3878f0b6b3d7d424b1b569d3e2e79
1 /**
2 * @file sipe-digest-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 * Digest routines implementation based on NSS.
26 * Includes: SHA1, MD5, HMAC_SHA_1, HMAC_MD5
29 #include "glib.h"
31 #include "nss.h"
33 * Work around a compiler error in NSS 3.13.x. Let's hope they fix it for
34 * 3.14.x. See also: https://bugzilla.mozilla.org/show_bug.cgi?id=702090
36 #if (NSS_VMAJOR == 3) && (NSS_VMINOR == 13)
37 #define __GNUC_MINOR __GNUC_MINOR__
38 #endif
39 #include "pk11pub.h"
41 #include "sipe-digest.h"
44 /* PRIVATE methods */
46 static PK11Context *sipe_digest_ctx_create(const SECOidTag algorithm)
48 PK11Context *context = PK11_CreateDigestContext(algorithm);
49 PK11_DigestBegin(context);
50 return(context);
53 static PK11Context*
54 sipe_digest_hmac_ctx_create(CK_MECHANISM_TYPE hmacMech, const guchar *key, gsize key_length)
56 PK11SlotInfo* slot;
57 SECItem keyItem;
58 SECItem noParams;
59 PK11SymKey* SymKey;
60 PK11Context* DigestContext;
62 /* For key */
63 slot = PK11_GetBestSlot(hmacMech, NULL);
65 keyItem.type = siBuffer;
66 keyItem.data = (unsigned char *)key;
67 keyItem.len = key_length;
69 SymKey = PK11_ImportSymKey(slot, hmacMech, PK11_OriginUnwrap, CKA_SIGN, &keyItem, NULL);
71 /* Parameter for crypto context */
72 noParams.type = siBuffer;
73 noParams.data = NULL;
74 noParams.len = 0;
76 DigestContext = PK11_CreateContextBySymKey(hmacMech, CKA_SIGN, SymKey, &noParams);
78 PK11_DigestBegin(DigestContext);
80 PK11_FreeSymKey(SymKey);
81 PK11_FreeSlot(slot);
83 return DigestContext;
86 static void sipe_digest_ctx_append(PK11Context* DigestContext, const guchar *data, gsize data_length)
88 PK11_DigestOp(DigestContext, data, data_length);
91 static void sipe_digest_ctx_digest(PK11Context* DigestContext, guchar *digest, gsize digest_length)
93 unsigned int len;
95 PK11_DigestFinal(DigestContext, digest, &len, digest_length);
98 static void sipe_digest_ctx_destroy(PK11Context* DigestContext)
100 PK11_DestroyContext(DigestContext, PR_TRUE);
103 static void sipe_digest(const SECOidTag algorithm,
104 const guchar *data, gsize data_length,
105 guchar *digest, gsize digest_length)
107 void *DigestContext;
109 DigestContext = sipe_digest_ctx_create(algorithm);
110 sipe_digest_ctx_append(DigestContext, data, data_length);
111 sipe_digest_ctx_digest(DigestContext, digest, digest_length);
112 sipe_digest_ctx_destroy(DigestContext);
115 static void sipe_digest_hmac(CK_MECHANISM_TYPE hmacMech,
116 const guchar *key, gsize key_length,
117 const guchar *data, gsize data_length,
118 guchar *digest, gsize digest_length)
120 void *DigestContext;
122 DigestContext = sipe_digest_hmac_ctx_create(hmacMech, key, key_length);
123 sipe_digest_ctx_append(DigestContext, data, data_length);
124 sipe_digest_ctx_digest(DigestContext, digest, digest_length);
125 sipe_digest_ctx_destroy(DigestContext);
129 /* PUBLIC methods */
131 void sipe_digest_md5(const guchar *data, gsize length, guchar *digest)
133 sipe_digest(SEC_OID_MD5, data, length, digest, SIPE_DIGEST_MD5_LENGTH);
136 void sipe_digest_sha1(const guchar *data, gsize length, guchar *digest)
138 sipe_digest(SEC_OID_SHA1, data, length, digest, SIPE_DIGEST_SHA1_LENGTH);
141 void sipe_digest_hmac_md5(const guchar *key, gsize key_length,
142 const guchar *data, gsize data_length,
143 guchar *digest)
145 sipe_digest_hmac(CKM_MD5_HMAC, key, key_length, data, data_length, digest, SIPE_DIGEST_HMAC_MD5_LENGTH);
148 void sipe_digest_hmac_sha1(const guchar *key, gsize key_length,
149 const guchar *data, gsize data_length,
150 guchar *digest)
152 sipe_digest_hmac(CKM_SHA_1_HMAC, key, key_length, data, data_length, digest, SIPE_DIGEST_HMAC_SHA1_LENGTH);
155 /* Stream HMAC(SHA1) digest for file transfer */
156 gpointer sipe_digest_ft_start(const guchar *sha1_digest)
158 /* used only the first 16 bytes of the 20 byte SHA1 digest */
159 return sipe_digest_hmac_ctx_create(CKM_SHA_1_HMAC, sha1_digest, 16);
162 void sipe_digest_ft_update(gpointer context, const guchar *data, gsize length)
164 sipe_digest_ctx_append(context, data, length);
167 void sipe_digest_ft_end(gpointer context, guchar *digest)
169 sipe_digest_ctx_digest(context, digest, SIPE_DIGEST_FILETRANSFER_LENGTH);
172 void sipe_digest_ft_destroy(gpointer context)
174 sipe_digest_ctx_destroy(context);
177 /* Stream digests, e.g. for TLS */
178 gpointer sipe_digest_md5_start(void)
180 return sipe_digest_ctx_create(SEC_OID_MD5);
183 void sipe_digest_md5_update(gpointer context, const guchar *data, gsize length)
185 sipe_digest_ctx_append(context, data, length);
188 void sipe_digest_md5_end(gpointer context, guchar *digest)
190 unsigned int saved_length;
191 /* save context to ensure this function can be called multiple times */
192 guchar *saved = PK11_SaveContextAlloc(context,
193 NULL,
195 &saved_length);
196 sipe_digest_ctx_digest(context, digest, SIPE_DIGEST_MD5_LENGTH);
197 PK11_RestoreContext(context, saved, saved_length);
198 PORT_Free(saved);
201 void sipe_digest_md5_destroy(gpointer context)
203 sipe_digest_ctx_destroy(context);
206 gpointer sipe_digest_sha1_start(void)
208 return sipe_digest_ctx_create(SEC_OID_SHA1);
211 void sipe_digest_sha1_update(gpointer context, const guchar *data, gsize length)
213 sipe_digest_ctx_append(context, data, length);
216 void sipe_digest_sha1_end(gpointer context, guchar *digest)
218 unsigned int saved_length;
219 /* save context to ensure this function can be called multiple times */
220 guchar *saved = PK11_SaveContextAlloc(context,
221 NULL,
223 &saved_length);
224 sipe_digest_ctx_digest(context, digest, SIPE_DIGEST_SHA1_LENGTH);
225 PK11_RestoreContext(context, saved, saved_length);
226 PORT_Free(saved);
229 void sipe_digest_sha1_destroy(gpointer context)
231 sipe_digest_ctx_destroy(context);
235 Local Variables:
236 mode: c
237 c-file-style: "bsd"
238 indent-tabs-mode: t
239 tab-width: 8
240 End: