2 * This file is part of the Nice GLib ICE library.
4 * (C) 2008-2009 Collabora Ltd.
5 * Contact: Youness Alaoui
6 * (C) 2007-2009 Nokia Corporation. All rights reserved.
7 * Contact: Rémi Denis-Courmont
9 * The contents of this file are subject to the Mozilla Public License Version
10 * 1.1 (the "License"); you may not use this file except in compliance with
11 * the License. You may obtain a copy of the License at
12 * http://www.mozilla.org/MPL/
14 * Software distributed under the License is distributed on an "AS IS" basis,
15 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
16 * for the specific language governing rights and limitations under the
19 * The Original Code is the Nice GLib ICE library.
21 * The Initial Developers of the Original Code are Collabora Ltd and Nokia
22 * Corporation. All Rights Reserved.
25 * Youness Alaoui, Collabora Ltd.
26 * Rémi Denis-Courmont, Nokia
28 * Alternatively, the contents of this file may be used under the terms of the
29 * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which
30 * case the provisions of LGPL are applicable instead of those above. If you
31 * wish to allow use of your version of this file only under the terms of the
32 * LGPL and not to allow others to use your version of this file under the
33 * MPL, indicate your decision by deleting the provisions above and replace
34 * them with the notice and other provisions required by the LGPL. If you do
35 * not delete the provisions above, a recipient may use your version of this
36 * file under either the MPL or the LGPL.
45 #include "stunmessage.h"
52 #include <openssl/hmac.h>
53 #include <openssl/sha.h>
55 #include <gnutls/gnutls.h>
56 #include <gnutls/crypto.h>
59 void stun_sha1 (const uint8_t *msg, size_t len, size_t msg_len, uint8_t *sha,
60 const void *key, size_t keylen, int padding)
62 uint16_t fakelen = htons (msg_len);
63 uint8_t pad_char[64] = {0};
78 #if (OPENSSL_VERSION_NUMBER < 0x10100000L) || \
79 (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL)
81 HMAC_CTX *ctx = &stackctx;
84 HMAC_CTX *ctx = HMAC_CTX_new ();
85 #endif /* OPENSSL_VERSION_NUMBER */
87 assert (SHA_DIGEST_LENGTH == 20);
89 TRY (HMAC_Init_ex (ctx, key, keylen, EVP_sha1(), NULL));
91 TRY (HMAC_Update (ctx, msg, 2));
92 TRY (HMAC_Update (ctx, (unsigned char *)&fakelen, 2));
93 TRY (HMAC_Update (ctx, msg + 4, len - 28));
95 /* RFC 3489 specifies that the message's size should be 64 bytes,
96 and \x00 padding should be done */
97 if (padding && ((len - 24) % 64) > 0) {
98 uint16_t pad_size = 64 - ((len - 24) % 64);
100 TRY (HMAC_Update (ctx, pad_char, pad_size));
103 TRY (HMAC_Final (ctx, sha, NULL));
105 #if (OPENSSL_VERSION_NUMBER < 0x10100000L) || \
106 (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL)
107 HMAC_CTX_cleanup (ctx);
110 #endif /* OPENSSL_VERSION_NUMBER */
114 gnutls_hmac_hd_t handle;
125 assert (gnutls_hmac_get_len (GNUTLS_MAC_SHA1) == 20);
126 TRY (gnutls_hmac_init (&handle, GNUTLS_MAC_SHA1, key, keylen));
128 TRY (gnutls_hmac (handle, msg, 2));
129 TRY (gnutls_hmac (handle, &fakelen, 2));
130 TRY (gnutls_hmac (handle, msg + 4, len - 28));
132 /* RFC 3489 specifies that the message's size should be 64 bytes,
133 and \x00 padding should be done */
134 if (padding && ((len - 24) % 64) > 0) {
135 uint16_t pad_size = 64 - ((len - 24) % 64);
137 TRY (gnutls_hmac (handle, pad_char, pad_size));
140 gnutls_hmac_deinit (handle, sha);
144 #endif /* HAVE_OPENSSL */
147 static const uint8_t *priv_trim_var (const uint8_t *var, size_t *var_len)
149 const uint8_t *ptr = var;
151 while (*ptr == '"') {
155 while(ptr[*var_len-1] == '"' ||
156 ptr[*var_len-1] == 0) {
164 void stun_hash_creds (const uint8_t *realm, size_t realm_len,
165 const uint8_t *username, size_t username_len,
166 const uint8_t *password, size_t password_len,
167 unsigned char md5[16])
169 const uint8_t *username_trimmed = priv_trim_var (username, &username_len);
170 const uint8_t *password_trimmed = priv_trim_var (password, &password_len);
171 const uint8_t *realm_trimmed = priv_trim_var (realm, &realm_len);
172 const uint8_t *colon = (uint8_t *)":";
177 #if (OPENSSL_VERSION_NUMBER < 0x10100000L) || \
178 (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL)
179 ctx = EVP_MD_CTX_create ();
181 ctx = EVP_MD_CTX_new ();
182 #endif /* OPENSSL_VERSION_NUMBER */
184 EVP_DigestInit_ex (ctx, EVP_md5(), NULL);
185 EVP_DigestUpdate (ctx, username_trimmed, username_len);
186 EVP_DigestUpdate (ctx, colon, 1);
187 EVP_DigestUpdate (ctx, realm_trimmed, realm_len);
188 EVP_DigestUpdate (ctx, colon, 1);
189 EVP_DigestUpdate (ctx, password_trimmed, password_len);
190 EVP_DigestFinal_ex (ctx, md5, NULL);
192 #if (OPENSSL_VERSION_NUMBER < 0x10100000L) || \
193 (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL)
194 EVP_MD_CTX_destroy (ctx);
196 EVP_MD_CTX_free (ctx);
197 #endif /* OPENSSL_VERSION_NUMBER */
200 gnutls_hash_hd_t handle;
202 gnutls_hash_init (&handle, GNUTLS_DIG_MD5);
203 gnutls_hash (handle, username_trimmed, username_len);
204 gnutls_hash (handle, colon, 1);
205 gnutls_hash (handle, realm_trimmed, realm_len);
206 gnutls_hash (handle, colon, 1);
207 gnutls_hash (handle, password_trimmed, password_len);
209 gnutls_hash_deinit (handle, md5);
210 #endif /* HAVE_OPENSSL */
214 void stun_make_transid (StunTransactionId id)
216 nice_RAND_nonce (id, 16);