📄 wtls_statesupport.c
字号:
/* ==================================================================== * The Kannel Software License, Version 1.0 * * Copyright (c) 2001-2004 Kannel Group * Copyright (c) 1998-2001 WapIT Ltd. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Kannel Group (http://www.kannel.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Kannel" and "Kannel Group" must not be used to * endorse or promote products derived from this software without * prior written permission. For written permission, please * contact org@kannel.org. * * 5. Products derived from this software may not be called "Kannel", * nor may "Kannel" appear in their name, without prior written * permission of the Kannel Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Kannel Group. For more information on * the Kannel Group, please see <http://www.kannel.org/>. * * Portions of this software are based upon software originally written at * WapIT Ltd., Helsinki, Finland for the Kannel project. */ /* * wtls_statesupport.c * * 2001 Nick Clarey, Yann Muller for 3G LAB */#include "gwlib/gwlib.h"#if (HAVE_WTLS_OPENSSL)#include <openssl/x509.h>#ifndef NO_RC5#include <openssl/rc5.h>#else#error "your OpenSSL installation lacks RC5 algorithm support"#endif#include "wtls_statesupport.h"#define BLOCKLENGTH 64#define INNERPAD 0x36#define OUTERPAD 0x5Cextern X509* x509_cert;extern RSA* private_key;extern KeyExchangeSuite client_key_exchange_algo;extern PublicKeyAlgorithm public_key_algo;extern SignatureAlgorithm signature_algo;Octstr* wtls_hmac_hash(Octstr* key, Octstr* data, WTLSMachine* wtls_machine);Octstr* wtls_hash(Octstr* inputData, WTLSMachine* wtls_machine);Octstr* wtls_encrypt_rc5(Octstr* data, WTLSMachine* wtls_machine);Octstr* wtls_decrypt_rc5(Octstr* encryptedData, WTLSMachine* wtls_machine);/* Add here the supported KeyExchangeSuites used by wtls_choose_clientkeyid */KeyExchangeSuite supportedKeyExSuite[] = { rsa_anon };Octstr* wtls_decrypt(Octstr* buffer, WTLSMachine* wtls_machine){ return wtls_decrypt_rc5(buffer,wtls_machine);}/* This function will convert our buffer into a completed GenericBlockCipher */Octstr* wtls_encrypt(Octstr* buffer, WTLSMachine* wtls_machine, int recordType){ Octstr* bufferCopy; Octstr* encryptedContent; Octstr* contentMac; Octstr* padding; Octstr* tempData; unsigned char* tempPadding; int paddingLength, contentLength, macSize, blockLength, sequenceNumber, bufferLength; int i; /* Copy our buffer */ bufferCopy = octstr_duplicate(buffer); /* Get the MAC of the content */ sequenceNumber = wtls_machine->server_seq_num; bufferLength = octstr_len(buffer); /* Copy the buffer in preparation for MAC calculation */ tempData = octstr_create(""); pack_int16(tempData, 0, sequenceNumber); octstr_append_char(tempData, recordType); pack_int16(tempData, octstr_len(tempData), bufferLength); octstr_append(tempData, buffer); /* Calculate the MAC */ contentMac = wtls_hmac_hash(wtls_machine->server_write_MAC_secret, tempData ,wtls_machine); /* Calculate the padding length */ contentLength = octstr_len(bufferCopy); macSize = hash_table[wtls_machine->mac_algorithm].mac_size; blockLength = bulk_table[wtls_machine->bulk_cipher_algorithm].block_size; paddingLength = (contentLength + macSize + 1) % (blockLength); /* Append the MAC to the bufferCopy */ octstr_append(bufferCopy,contentMac); if (paddingLength > 0) { /* Pad with the paddingLength itself paddingLength times. Confused yet? */ tempPadding = gw_malloc(paddingLength); for (i=0;i < paddingLength; i++) { /* You're probably really spaced out around now... see section 9.2.3.3 for more details... */ tempPadding[i] = paddingLength; } octstr_append_data(bufferCopy, tempPadding, paddingLength); } /* Add the length byte */ octstr_append_char(bufferCopy, paddingLength); /* Encrypt the content */ encryptedContent = wtls_encrypt_rc5(bufferCopy,wtls_machine); return encryptedContent;}/* P_hash as described in WAP WTLS section 11.3.2 */Octstr* wtls_P_hash(Octstr* secret, Octstr* seed, int byteLength, WTLSMachine* wtls_machine){ Octstr *a; Octstr *aPrev; Octstr *aPlusSeed; Octstr *hashTemp; Octstr *hashedData; hashedData = octstr_create(""); /* start with A(1) = HMAC_hash(secret, seed) */ aPrev = octstr_duplicate(seed); do { /* A(i) */ a = wtls_hmac_hash(secret, aPrev, wtls_machine); aPlusSeed = octstr_cat(a, seed); /* HMAC */ hashTemp = wtls_hmac_hash(secret, aPlusSeed, wtls_machine); octstr_append(hashedData, hashTemp); octstr_destroy(hashTemp); /* Update a(i-1) */ octstr_destroy(aPrev); aPrev = a; } while(octstr_len(hashedData) < byteLength); gw_free(aPlusSeed); return hashedData;}/* Pseudo Random Function (PRF) as described in WAP WTLS section 11.3.2 */Octstr* wtls_calculate_prf(Octstr* secret, Octstr* label, Octstr* seed, int byteLength, WTLSMachine* wtls_machine){ Octstr* returnOctstr; Octstr *labelPlusSeed; /* Create label + seed */ labelPlusSeed = octstr_cat(label, seed); /* PRF(secret, label, seed) = P_hash(secret, label + seed) */ returnOctstr = wtls_P_hash(secret, labelPlusSeed, byteLength, wtls_machine); /* Return the first nbytes of the hashed data */ octstr_truncate(returnOctstr, byteLength); gw_free(labelPlusSeed); return returnOctstr; }/* MAC calculation */Octstr* wtls_hmac_hash(Octstr* key, Octstr* data, WTLSMachine* wtls_machine){ static unsigned char final_mac[1024]; unsigned char *mac, *buffer, *keyString; int mac_len, bufferlen, keylen; Octstr *returnOctstr; buffer = octstr_get_cstr(data); bufferlen = octstr_len(data); keyString = octstr_get_cstr(key); keylen = octstr_len(key); mac = final_mac; switch (wtls_machine->mac_algorithm) { case SHA_0: /* no keyed MAC is calculated */ /* So what do we return ? */ break; case SHA_40: case SHA_80: case SHA_NOLIMIT: HMAC(EVP_sha1(), keyString, keylen, buffer, bufferlen, mac, &mac_len); break; case SHA_XOR_40: // dunno yet break; case MD5_40: case MD5_80: case MD5_NOLIMIT: HMAC(EVP_md5(), keyString, keylen, buffer, bufferlen, mac, &mac_len); break; } returnOctstr = octstr_create_from_data(mac, mac_len);}/* Not to be confused with octstr_hash, this applies the currently set hashing algorithm from wtls_machine to the supplied input data, returning a hashed Octstr. If it fails, it will return a NULL pointer */Octstr* wtls_hash(Octstr* inputData, WTLSMachine* wtls_machine){ int inputDataLength; int outputDataLength; unsigned char* outputDataTemp; unsigned char* inputDataTemp; unsigned char* tempPointer; Octstr* outputData; inputDataLength = octstr_len(inputData); outputDataLength = hash_table[wtls_machine->mac_algorithm].key_size; inputDataTemp = gw_malloc(inputDataLength); outputDataTemp = gw_malloc(outputDataLength); /* Copy the contents of inputData into inputDataTemp, ready for hashing */ tempPointer = octstr_get_cstr(inputData); memcpy((void*) inputDataTemp, (void*)tempPointer, inputDataLength); /* Hash away! */ // Here's where we need to hash on the selected algorithm, not just the SHA-1 algorithm //debug("wtls", 0, "mac algo %d", wtls_machine->mac_algorithm); switch (wtls_machine->mac_algorithm) { case SHA_0: /* no keyed MAC is calculated */ // So what do we return ? break; case SHA_40: case SHA_80: case SHA_NOLIMIT: tempPointer = SHA1(inputDataTemp, inputDataLength, outputDataTemp); break; case SHA_XOR_40: // dunno yet break; case MD5_40: case MD5_80: case MD5_NOLIMIT: tempPointer = MD5(inputDataTemp, inputDataLength, outputDataTemp); break; } if (tempPointer == NULL){ /* Pop out an error */ } /* Get our output data setup */ outputData = octstr_create_from_data(outputDataTemp,outputDataLength); /* some algorithms don't use the full length of H */ octstr_truncate(outputData, hash_table[wtls_machine->mac_algorithm].mac_size); /* Delete our allocated memory */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -