wtls_statesupport.c
上传用户:gzpyjq
上传日期:2013-01-31
资源大小:1852k
文件大小:29k
源码类别:

手机WAP编程

开发平台:

WINDOWS

  1. /* 
  2.  * wtls_statesupport.c
  3.  * 
  4.  * 2001  Nick Clarey, Yann Muller for 3G LAB
  5.  */
  6. #include "gwlib/gwlib.h"
  7. #if (HAVE_WTLS_OPENSSL)
  8. #include <openssl/x509.h>
  9. #ifndef NO_RC5
  10. #include <openssl/rc5.h>
  11. #else
  12. #error "your OpenSSL installation lacks RC5 algorithm support"
  13. #endif
  14. #include "wtls_statesupport.h"
  15. #define BLOCKLENGTH 64
  16. #define INNERPAD 0x36
  17. #define OUTERPAD 0x5C
  18. extern X509* x509_cert;
  19. extern RSA* private_key;
  20. extern KeyExchangeSuite client_key_exchange_algo;
  21. extern PublicKeyAlgorithm public_key_algo;
  22. extern SignatureAlgorithm signature_algo;
  23. Octstr* wtls_hmac_hash(Octstr* key, Octstr* data, WTLSMachine* wtls_machine);
  24. Octstr* wtls_hash(Octstr* inputData, WTLSMachine* wtls_machine);
  25. Octstr* wtls_encrypt_rc5(Octstr* data, WTLSMachine* wtls_machine);
  26. Octstr* wtls_decrypt_rc5(Octstr* encryptedData, WTLSMachine* wtls_machine);
  27. /* Add here the supported KeyExchangeSuites 
  28.    used by wtls_choose_clientkeyid */
  29. KeyExchangeSuite supportedKeyExSuite[] = { rsa_anon };
  30. Octstr* wtls_decrypt(Octstr* buffer, WTLSMachine* wtls_machine)
  31. {
  32.         return wtls_decrypt_rc5(buffer,wtls_machine);
  33. }
  34. /* This function will convert our buffer into a completed GenericBlockCipher */
  35. Octstr* wtls_encrypt(Octstr* buffer, WTLSMachine* wtls_machine, int recordType)
  36. {
  37.         Octstr* bufferCopy;
  38.         Octstr* encryptedContent;
  39.         Octstr* contentMac;
  40.         Octstr* padding;
  41.         Octstr* tempData;
  42.         unsigned char* tempPadding;
  43.         
  44.         int paddingLength, contentLength, macSize, blockLength,
  45.                 sequenceNumber, bufferLength;
  46.         int i;
  47.         /* Copy our buffer */
  48.         bufferCopy = octstr_duplicate(buffer);
  49.         
  50.         /* Get the MAC of the content */
  51.         sequenceNumber = wtls_machine->server_seq_num;
  52.         bufferLength  = octstr_len(buffer);
  53.         /* Copy the buffer in preparation for MAC calculation */
  54.         tempData = octstr_create("");
  55.         pack_int16(tempData, 0, sequenceNumber);
  56.         octstr_append_char(tempData, recordType);
  57.         pack_int16(tempData, octstr_len(tempData), bufferLength);        
  58.         octstr_append(tempData, buffer);
  59.         /* Calculate the MAC */
  60.         contentMac = wtls_hmac_hash(wtls_machine->server_write_MAC_secret, tempData ,wtls_machine);
  61.         /* Calculate the padding length */
  62.         contentLength = octstr_len(bufferCopy);
  63.         macSize = hash_table[wtls_machine->mac_algorithm].mac_size;
  64.         blockLength = bulk_table[wtls_machine->bulk_cipher_algorithm].block_size;
  65.         paddingLength = (contentLength + macSize + 1) % (blockLength);
  66.         /* Append the MAC to the bufferCopy */
  67.         octstr_append(bufferCopy,contentMac);
  68.         
  69.         if (paddingLength > 0) {
  70.                 /* Pad with the paddingLength itself paddingLength times. Confused yet? */
  71.                 tempPadding = gw_malloc(paddingLength);
  72.                 for (i=0;i < paddingLength; i++) {
  73.                         /* You're probably really spaced out around now...
  74.                            see section 9.2.3.3 for more details... */
  75.                         tempPadding[i] = paddingLength;
  76.                 }
  77.                 octstr_append_data(bufferCopy, tempPadding, paddingLength);
  78.         }
  79.         /* Add the length byte */
  80.         octstr_append_char(bufferCopy, paddingLength);                
  81.         /* Encrypt the content */
  82.         encryptedContent =  wtls_encrypt_rc5(bufferCopy,wtls_machine);
  83.         return encryptedContent;
  84. }
  85. /* P_hash as described in WAP WTLS section 11.3.2 */
  86. Octstr* wtls_P_hash(Octstr* secret, Octstr* seed, int byteLength, WTLSMachine* wtls_machine)
  87. {
  88. Octstr *a;
  89. Octstr *aPrev;
  90. Octstr *aPlusSeed;
  91. Octstr *hashTemp;
  92. Octstr *hashedData;
  93. hashedData = octstr_create("");
  94. /* start with A(1) = HMAC_hash(secret, seed) */
  95. aPrev = octstr_duplicate(seed);
  96. do {
  97. /* A(i) */
  98. a = wtls_hmac_hash(secret, aPrev, wtls_machine);
  99. aPlusSeed = octstr_cat(a, seed);
  100. /* HMAC */
  101. hashTemp = wtls_hmac_hash(secret, aPlusSeed, wtls_machine);
  102. octstr_append(hashedData, hashTemp);
  103. octstr_destroy(hashTemp);
  104. /* Update a(i-1) */
  105. octstr_destroy(aPrev);
  106. aPrev = a;
  107. } while(octstr_len(hashedData) < byteLength);
  108. gw_free(aPlusSeed);
  109. return hashedData;
  110. }
  111. /* Pseudo Random Function (PRF) as described in WAP WTLS section 11.3.2 */
  112. Octstr* wtls_calculate_prf(Octstr* secret, Octstr* label,
  113.                            Octstr* seed, int byteLength, WTLSMachine* wtls_machine)
  114. {
  115.         Octstr* returnOctstr;
  116.      Octstr *labelPlusSeed;
  117.      /* Create label + seed */
  118. labelPlusSeed = octstr_cat(label, seed);
  119. /* PRF(secret, label, seed) = P_hash(secret, label + seed) */
  120. returnOctstr = wtls_P_hash(secret, labelPlusSeed, byteLength, wtls_machine);
  121.      /* Return the first nbytes of the hashed data */
  122. octstr_truncate(returnOctstr, byteLength);
  123.  
  124.      gw_free(labelPlusSeed);
  125.      return returnOctstr;
  126. }
  127. /* MAC calculation */
  128. Octstr* wtls_hmac_hash(Octstr* key, Octstr* data, WTLSMachine* wtls_machine)
  129. {
  130.     static unsigned char final_mac[1024];
  131.     unsigned char *mac, *buffer, *keyString;
  132. int mac_len, bufferlen, keylen;
  133. Octstr *returnOctstr;
  134. buffer = octstr_get_cstr(data);
  135. bufferlen = octstr_len(data);
  136.     keyString = octstr_get_cstr(key);
  137. keylen = octstr_len(key);
  138. mac = final_mac;
  139.     switch (wtls_machine->mac_algorithm) {
  140. case SHA_0:
  141. /* no keyed MAC is calculated */
  142. /* So what do we return ? */
  143. break;
  144. case SHA_40:
  145. case SHA_80:
  146. case SHA_NOLIMIT:
  147.      HMAC(EVP_sha1(), keyString, keylen,
  148.  buffer, bufferlen,
  149.           mac, &mac_len);
  150. break;
  151. case SHA_XOR_40:
  152. // dunno yet
  153. break;
  154. case MD5_40:
  155. case MD5_80:
  156. case MD5_NOLIMIT:
  157.      HMAC(EVP_md5(), keyString, keylen,
  158.  buffer, bufferlen,
  159.           mac, &mac_len);
  160. break;
  161. }
  162.     returnOctstr = octstr_create_from_data(mac, mac_len);
  163. }
  164. /* Not to be confused with octstr_hash, this applies the currently set hashing
  165.    algorithm from wtls_machine to the supplied input data, returning a hashed
  166.    Octstr. If it fails, it will return a NULL pointer */
  167. Octstr* wtls_hash(Octstr* inputData, WTLSMachine* wtls_machine)
  168. {
  169.         int inputDataLength;
  170.         int outputDataLength;
  171.         unsigned char* outputDataTemp;
  172.         unsigned char* inputDataTemp;
  173.         unsigned char* tempPointer;
  174.         Octstr* outputData;
  175.         inputDataLength = octstr_len(inputData);
  176.         outputDataLength = hash_table[wtls_machine->mac_algorithm].key_size;
  177.         inputDataTemp = gw_malloc(inputDataLength);
  178.         outputDataTemp = gw_malloc(outputDataLength);
  179.         /* Copy the contents of inputData into inputDataTemp, ready for hashing */
  180.         tempPointer = octstr_get_cstr(inputData);
  181.         memcpy((void*) inputDataTemp, (void*)tempPointer, inputDataLength);
  182.         
  183.         /* Hash away! */
  184.         // Here's where we need to hash on the selected algorithm, not just the SHA-1 algorithm
  185. //debug("wtls", 0, "mac algo %d", wtls_machine->mac_algorithm);
  186.         switch (wtls_machine->mac_algorithm) {
  187. case SHA_0:
  188. /* no keyed MAC is calculated */
  189. // So what do we return ?
  190. break;
  191. case SHA_40:
  192. case SHA_80:
  193. case SHA_NOLIMIT:
  194. tempPointer = SHA1(inputDataTemp, inputDataLength, outputDataTemp);
  195. break;
  196. case SHA_XOR_40:
  197. // dunno yet
  198. break;
  199. case MD5_40:
  200. case MD5_80:
  201. case MD5_NOLIMIT:
  202. tempPointer = MD5(inputDataTemp, inputDataLength, outputDataTemp);
  203. break;
  204. }
  205.         if (tempPointer == NULL){
  206.                 /* Pop out an error */
  207.         }
  208.         /* Get our output data setup */
  209.         outputData = octstr_create_from_data(outputDataTemp,outputDataLength);
  210.         
  211. /* some algorithms don't use the full length of H */
  212.         octstr_truncate(outputData, hash_table[wtls_machine->mac_algorithm].mac_size);
  213.         /* Delete our allocated memory */
  214.         gw_free(outputDataTemp);
  215.         gw_free(inputDataTemp);
  216.         outputDataTemp = NULL;
  217.         inputDataTemp = NULL;
  218.         
  219.         /* Return the outputData */
  220.         return outputData;
  221. }
  222. Octstr* wtls_decrypt_rc5(Octstr* data, WTLSMachine* wtls_machine)
  223. {
  224.         Octstr* encryptedData;
  225.         Octstr* decryptedData;
  226.         Octstr* duplicatedIv;
  227.         unsigned char* output;
  228.         unsigned char* input;
  229.         unsigned char* iv;
  230.         unsigned char* keyData;
  231.         int keyLen;
  232.         int ivLen;
  233.         int dataLen;
  234.         
  235.         RC5_32_KEY* key = NULL;
  236.         ivLen = bulk_table[wtls_machine->bulk_cipher_algorithm].iv_size;
  237.         duplicatedIv = octstr_duplicate(wtls_machine->client_write_IV);
  238.         iv = octstr_get_cstr(duplicatedIv);
  239.         keyLen = bulk_table[wtls_machine->bulk_cipher_algorithm].key_material;
  240.         keyData = octstr_get_cstr(wtls_machine->client_write_enc_key);
  241.         dataLen = octstr_len(data);
  242.         input = octstr_get_cstr(data);
  243.         
  244.         key = gw_malloc (sizeof(RC5_32_KEY));
  245.         
  246.         /* Key generation */
  247.         RC5_32_set_key(key, keyLen, keyData,  RC5_16_ROUNDS);
  248.         
  249.         /* Malloc our output */
  250.         output = gw_malloc (dataLen);
  251.         
  252.         /* Encrypt the string */
  253.          debug("wtls_statesupport",0,"About to decrypt: dataLen = %d, iv = %x", dataLen, iv);
  254.          octstr_dump(data,0);
  255.          RC5_32_cbc_encrypt(input, output, dataLen, key, iv, RC5_DECRYPT);
  256.          debug("wtls_statesupport",0,"Decrypted");
  257.          decryptedData = octstr_create_from_data(output, dataLen);
  258.          octstr_dump(decryptedData,0);         
  259.          /* Encrypt it just to test */
  260.          gw_free(output);
  261.          output = NULL;
  262.          output = gw_malloc (dataLen);
  263.          
  264.           /* Ensure that we preserve the iv */
  265.          octstr_destroy(duplicatedIv);
  266.          duplicatedIv = octstr_duplicate(wtls_machine->client_write_IV);
  267.          iv = octstr_get_cstr(duplicatedIv);
  268.          octstr_get_many_chars(iv, wtls_machine->client_write_IV,0,ivLen);         
  269.          input = octstr_get_cstr(decryptedData);
  270.         
  271.          RC5_32_cbc_encrypt(input, output, dataLen, key, iv, RC5_ENCRYPT);
  272.          encryptedData = octstr_create_from_data(output, dataLen);
  273.          
  274.          gw_free(output);
  275.          output = NULL;
  276.          octstr_destroy(duplicatedIv);
  277.          return decryptedData;
  278. }
  279. Octstr* wtls_encrypt_rc5(Octstr* data, WTLSMachine* wtls_machine)
  280. {
  281.         Octstr* encryptedData;
  282.         Octstr* decryptedData;
  283.         Octstr* duplicatedIv;
  284.         unsigned char* output;
  285.         unsigned char* input;
  286.         unsigned char* iv;
  287.         unsigned char* keyData;
  288.         int keyLen;
  289.         int ivLen;
  290.         int dataLen;
  291.         
  292.         RC5_32_KEY* key = NULL;
  293.         ivLen = bulk_table[wtls_machine->bulk_cipher_algorithm].iv_size;
  294.         duplicatedIv = octstr_duplicate(wtls_machine->server_write_IV);
  295.         iv = octstr_get_cstr(duplicatedIv);
  296.         keyLen = bulk_table[wtls_machine->bulk_cipher_algorithm].key_material;
  297.         keyData = octstr_get_cstr(wtls_machine->server_write_enc_key);
  298.         dataLen = octstr_len(data);
  299.         input = octstr_get_cstr(data);
  300.         
  301.         key = gw_malloc (sizeof(RC5_32_KEY));
  302.         
  303.         /* Key generation */
  304.         debug("wtls_statesupport",0,"Key generation");
  305.         RC5_32_set_key(key, keyLen, keyData,  RC5_16_ROUNDS);
  306.         
  307.         /* Malloc our output */
  308.         output = gw_malloc (dataLen);
  309.         
  310.         /* Encrypt the string */
  311.          RC5_32_cbc_encrypt(input, output, dataLen, key, iv, RC5_ENCRYPT);
  312.          encryptedData = octstr_create_from_data(output, dataLen);
  313.          /* Decrypt it just to test */
  314.          gw_free(output);
  315.          output = NULL;
  316.          output = gw_malloc (dataLen);
  317.          
  318.           /* Ensure that we preserve the iv */
  319.          octstr_destroy(duplicatedIv);
  320.          duplicatedIv = octstr_duplicate(wtls_machine->server_write_IV);
  321.          iv = octstr_get_cstr(duplicatedIv);
  322.          octstr_get_many_chars(iv, wtls_machine->server_write_IV,0,ivLen);         
  323.          input = octstr_get_cstr(encryptedData);
  324.         
  325.          RC5_32_cbc_encrypt(input, output, dataLen, key, iv, RC5_DECRYPT);
  326.          decryptedData = octstr_create_from_data(output, dataLen);
  327.          gw_free(output);
  328.          output = NULL;
  329.          octstr_destroy(duplicatedIv);
  330.          return encryptedData;
  331. }
  332. Octstr* wtls_decrypt_rsa(Octstr* encryptedData)
  333. {
  334.         int numBytesWritten=0,numBytesToRead=0;
  335.         Octstr *decryptedData=0;
  336.         unsigned char* tempDecryptionBuffer=0;
  337.         char* tempEncryptionPointer=0;
  338.         
  339.         /* Allocate some memory for our decryption buffer */
  340.         tempDecryptionBuffer = gw_malloc(RSA_size(private_key));
  341.         /* Calculate the number of bytes to read from encryptedData when decrypting */
  342.         numBytesToRead = octstr_len(encryptedData);
  343.         /* Don't write to this pointer. Ever ever ever. */
  344.         tempEncryptionPointer = octstr_get_cstr(encryptedData);
  345.         
  346.         /* Decrypt the data in encryptedData */
  347.         numBytesWritten = RSA_private_decrypt(numBytesToRead, tempEncryptionPointer,
  348.                                               tempDecryptionBuffer, private_key, RSA_PKCS1_PADDING);
  349. if(numBytesWritten == -1) {
  350. tempEncryptionPointer += 2;
  351. numBytesToRead -= 2;
  352.         numBytesWritten = RSA_private_decrypt(numBytesToRead, tempEncryptionPointer,
  353.                                               tempDecryptionBuffer, private_key, RSA_PKCS1_PADDING);
  354. }
  355.  
  356.         /* Move the tempDecryptionBuffer to an Octstr */
  357.         decryptedData = octstr_create_from_data(tempDecryptionBuffer,numBytesWritten);
  358.         /* Deallocate the tempDecryptionBuffer */
  359.         gw_free(tempDecryptionBuffer);
  360.         tempDecryptionBuffer = NULL;
  361. debug("wtls",0, "Decrypted secret");
  362. octstr_dump(   decryptedData, 0);
  363.      
  364.         /* Return the decrypted data */
  365.         return decryptedData;
  366. }
  367. void wtls_decrypt_pdu_list(WTLSMachine *wtls_machine, List *pdu_list)
  368. {
  369. int i, listlen;
  370.     Octstr* decryptedData = NULL;
  371. wtls_Payload *payload;
  372. listlen = list_len(pdu_list);
  373. for( i=0; i<listlen; i++) {
  374. payload = (wtls_Payload *)list_get(pdu_list, i);
  375. if(payload->cipher) {
  376. debug("wtls", 0, "Decrypting PDU %d", i);
  377.             decryptedData = wtls_decrypt(payload->data, wtls_machine);
  378. /* replace the data */
  379. octstr_destroy(payload->data);
  380. payload->data = decryptedData;
  381. }
  382. else {
  383. debug("wtls", 0, "PDU %d is not encrypted.", i);
  384. }
  385. }
  386. }
  387. RSAPublicKey* wtls_get_rsapublickey(void)
  388. {
  389.         RSA* rsaStructure=0;
  390.         EVP_PKEY* publicKey=0;
  391.         BIGNUM *modulus=0,*exponent=0;
  392.         unsigned char* tempModulusStorage=0,*tempExponentStorage=0;
  393.         int numbytes=0;
  394.         RSAPublicKey* returnStructure=0;
  395.         Octstr *octstrModulus=0, *octstrExponent=0;
  396.         
  397.         /* First, we need to extract the RSA structure from the X509 Cert */
  398.         /* Get the EVP_PKEY structure from the X509 cert */
  399.         publicKey = X509_PUBKEY_get(x509_cert->cert_info->key);
  400.         
  401.         /* Take said EVP_PKEY structure and get the RSA component */
  402.         if (EVP_PKEY_type(publicKey->type) != EVP_PKEY_RSA)
  403.         {
  404.                 return NULL;
  405.         }
  406.         else
  407.         {
  408.                 rsaStructure = publicKey->pkey.rsa;
  409.         }
  410.         
  411.         /* Then we need to grab the exponent component from the cert */
  412.         exponent = rsaStructure->e;
  413.         
  414.         /* We need to allocate sufficient memory to hold the exponent */
  415.         numbytes = BN_num_bytes(exponent);
  416.         tempExponentStorage = gw_malloc(numbytes);
  417.         
  418.         /* Then we get the exponent */
  419.         numbytes = BN_bn2bin(exponent, tempExponentStorage);
  420.         
  421.         /* And finally we convert the exponent to an Octstr */
  422.         octstrExponent = octstr_create_from_data(tempExponentStorage,numbytes);
  423.         /* Then we need to grab the modulus component from the cert */
  424.         modulus = rsaStructure->n;
  425.         
  426.         /* We need to allocate sufficient memory to hold the modulus */
  427.         numbytes = BN_num_bytes(modulus);
  428.         tempModulusStorage = gw_malloc(numbytes);
  429.         
  430.         /* Then we get the modulus */
  431.         numbytes = BN_bn2bin(modulus, tempModulusStorage);
  432.         
  433.         /* And finally we convert the modulus to an Octstr */
  434.         octstrModulus = octstr_create_from_data(tempModulusStorage,numbytes);
  435.         /* Put the components into our return structure */
  436.         returnStructure = gw_malloc(sizeof(RSAPublicKey));
  437.         returnStructure->rsa_exponent = octstrExponent;
  438.         returnStructure->rsa_modulus = octstrModulus;
  439.         
  440.         /* And deallocate the memory allocated for holding the modulus */
  441.         gw_free(tempModulusStorage);
  442.         gw_free(tempExponentStorage);
  443.         tempModulusStorage = NULL;
  444.         tempExponentStorage = NULL;
  445.         
  446.         return returnStructure;
  447. }
  448. Octstr* wtls_get_certificate(void)
  449. {
  450.         unsigned char** pp;
  451.         unsigned char* ppStart;
  452.         int amountWritten = 1260;
  453.         Octstr* returnOctstr;
  454.         
  455.         debug("wtls_get_certificate",0,"x509_cert : %x", x509_cert);
  456.         /* Convert the x509 certificate to DER-encoding */
  457.         amountWritten =i2d_X509(x509_cert, NULL);
  458.         debug("wtls_get_certificate",0,"amountWritten : %d", amountWritten);
  459.         /* Allocate some memory for *pp */
  460.         pp = (unsigned char**) gw_malloc(sizeof(unsigned char**));
  461.         
  462.         /* Allocate the memory and call the same function again?!!?
  463.            What an original idea :-/ */
  464.         ppStart = (unsigned char *) gw_malloc (sizeof(unsigned char)*amountWritten);
  465.         debug("wtls_get_certificate",0,"x509_cert_DER_pre : %x", *pp);
  466.         *pp = ppStart;
  467.         amountWritten =i2d_X509(x509_cert, pp);
  468.         /* And we do this, because otherwise *pp is pointing to the end of the buffer. Yay */
  469.         *pp = ppStart;
  470.         debug("wtls_get_certificate",0,"x509_cert_DER_post : %x", *pp);
  471.         
  472.         /* Convert the DER-encoded char string to an octstr */
  473.         returnOctstr = octstr_create_from_data(*pp,amountWritten);
  474.         /* Destroy the memory allocated temporarily above */
  475.         gw_free(*pp);
  476.         *pp = NULL;
  477.         
  478.         /* Destroy the memory allocated for pp as well */
  479.         gw_free(pp);
  480.         pp = NULL;
  481.         
  482.         /* Return the octstr */
  483.         return returnOctstr;
  484. }
  485. /* Chooses a CipherSuite from the list provided by the client.
  486.    Returns NULL if none is acceptable. */
  487. CipherSuite* wtls_choose_ciphersuite(List* ciphersuites) {
  488.         CipherSuite* returnSuite = NULL;
  489.         CipherSuite* currentCS = NULL;
  490. int i = 0;
  491.         int listLen;
  492. listLen = list_len(ciphersuites);
  493.         //returnSuite = gw_malloc(sizeof(CipherSuite));
  494. /* the first CS in the list */
  495. do {
  496. /* the next CS in the list */
  497. currentCS = list_get(ciphersuites, i);
  498. /* Check if we support this BulkCipher */
  499. if(currentCS->bulk_cipher_algo >= RC5_CBC_40 &&
  500.    currentCS->bulk_cipher_algo <= IDEA_CBC) {
  501. /* Check if we support this MAC algsorithm */
  502. if(currentCS->mac_algo >= SHA_0 &&
  503.    currentCS->mac_algo <= MD5_NOLIMIT) {
  504. /* We can use this CipherSuite then */
  505. returnSuite = currentCS;
  506. }
  507. }
  508. i++;
  509. } while(returnSuite == NULL && i < listLen);
  510.         return returnSuite;
  511. }
  512. int isSupportedKeyEx(int keyExId) {
  513. int maxSupported;
  514. int i;
  515. int retCode = 0;
  516. maxSupported = sizeof(supportedKeyExSuite) / sizeof(KeyExchangeSuite);
  517. for(i = 0; i<maxSupported; i++) {
  518. if(keyExId == supportedKeyExSuite[i]) {
  519. retCode = 1;
  520. }
  521. }
  522. return retCode;
  523. }
  524. int wtls_choose_clientkeyid(List* clientKeyIds) {
  525. int returnKey = 0;
  526. KeyExchangeId *currentKeyId = NULL;
  527. int i = 0;
  528. int listLen;
  529. listLen = list_len(clientKeyIds);
  530. debug("wtls", 0, "listLen = %d", listLen);
  531. do {
  532. currentKeyId = list_get(clientKeyIds, i);
  533. debug("wtls", 0, "Key %d", i);
  534. dump_key_exchange_id("wtls", 0, currentKeyId);
  535. /* check if the current key suite is supported */
  536. if(isSupportedKeyEx(currentKeyId->key_exchange_suite)) {
  537. returnKey = i+1;
  538. }
  539. i++;
  540. } while(returnKey == 0 && i < listLen);
  541.         return returnKey;
  542. }
  543. int wtls_choose_snmode(int snmode)
  544. {
  545.         return 2;
  546. }
  547. int wtls_choose_krefresh(int krefresh)
  548. {
  549.         return 2;
  550. }
  551. Random* wtls_get_random(void)
  552. {
  553.         Random* randomData;
  554.         randomData = gw_malloc(sizeof(Random));
  555.         randomData->gmt_unix_time = 0x0000;
  556.         /* Yeah, I know, it's not very random */
  557.         randomData->random_bytes = octstr_create("000000000000");
  558.         return randomData;
  559. }
  560. int clienthellos_are_identical (List* pdu_list, List* last_received_packet)
  561. {
  562.         return 0;
  563. }
  564. int certifcateverifys_are_identical (List* pdu_list, List* last_received_packet)
  565. {
  566.         return 0;
  567. }
  568. int certificates_are_identical (List* pdu_list, List* last_received_packet)
  569. {
  570.         return 0;
  571. }
  572. int clientkeyexchanges_are_identical (List* pdu_list, List* last_received_packet)
  573. {
  574.         return 0;
  575. }
  576. int changecipherspecs_are_identical (List* pdu_list, List* last_received_packet)
  577. {
  578.         return 0;
  579. }
  580. int finisheds_are_indentical (List* pdu_list, List* last_received_packet)
  581. {
  582.         return 0;
  583. }
  584. int packet_contains_changecipherspec (List* pdu_list)
  585. {
  586.         return 0;
  587. }
  588. int packet_contains_finished (List* pdu_list)
  589. {
  590.         return 0;
  591. }
  592. int packet_contains_optional_stuff (List* pdu_list)
  593. {
  594.         return 0;
  595. }
  596. int packet_contains_userdata (List* pdu_list)
  597. {
  598. /* FIXME: need to check if it is really Userdata !! */
  599.         return 1;
  600. }
  601. int packet_contains_clienthello (List* pdu_list)
  602. {
  603.         return 0;
  604. }
  605. int is_critical_alert (List* pdu_list)
  606. {
  607.         return 0;
  608. }
  609. int is_warning_alert (List* pdu_list)
  610. {
  611.         return 0;
  612. }
  613. /* go through the list of wtls_Payloads and add the data of any 
  614.    handshake message to wtls_machine->handshake_data */
  615. void add_all_handshake_data(WTLSMachine *wtls_machine, List *pdu_list)
  616. {
  617. long i, listlen;
  618. wtls_Payload *payload;
  619. gw_assert(pdu_list != NULL);
  620. listlen = list_len(pdu_list);
  621. debug("wtls", 0,"adding handshake data from %d PDU(s)", listlen);
  622. for(i=0; i<listlen; i++) {
  623. payload = (wtls_Payload *)list_get(pdu_list, i);
  624. if(payload->type == Handshake_PDU) {
  625.             octstr_insert(wtls_machine->handshake_data, payload->data,
  626.                           octstr_len(wtls_machine->handshake_data));
  627. debug("wtls", 0, "Data from PDU %d:", i);
  628. octstr_dump(payload->data, 2);
  629. }
  630. }
  631. }
  632. void calculate_server_key_block(WTLSMachine *wtls_machine)
  633. {
  634.     Octstr* concatenatedRandoms=0;
  635.     Octstr* labelMaster=0;
  636.     Octstr* key_block;
  637.     Octstr* final_server_write_enc_key = NULL;
  638.     Octstr* final_server_write_IV = NULL;
  639.     Octstr* emptySecret = NULL;
  640.     /* Concatenate our random data */
  641.     concatenatedRandoms = octstr_create("");
  642.     pack_int16(concatenatedRandoms, 0, wtls_machine->server_seq_num);
  643.     octstr_append(concatenatedRandoms, wtls_machine->server_random);
  644.     octstr_append(concatenatedRandoms, wtls_machine->client_random);
  645.     /* Calculate the key_block */
  646.     labelMaster = octstr_create("server expansion");
  647.     key_block = wtls_calculate_prf(wtls_machine->master_secret, labelMaster,
  648.                                    concatenatedRandoms,
  649.                                    hash_table[wtls_machine->mac_algorithm].key_size
  650.                                    + bulk_table[wtls_machine->bulk_cipher_algorithm].key_material
  651.                                    + bulk_table[wtls_machine->bulk_cipher_algorithm].iv_size,
  652.                                    wtls_machine );
  653.     octstr_destroy(labelMaster);
  654.     labelMaster = NULL;
  655.     octstr_destroy(concatenatedRandoms);
  656.     concatenatedRandoms = NULL;
  657.     /* Break the key_block in its 3 parts */
  658.     wtls_machine->server_write_MAC_secret = octstr_copy(key_block, 0, hash_table[wtls_machine->mac_algorithm].key_size);
  659.     octstr_delete(key_block, 0, hash_table[wtls_machine->mac_algorithm].key_size);
  660.     wtls_machine->server_write_enc_key = octstr_copy(key_block, 0, bulk_table[wtls_machine->bulk_cipher_algorithm].key_material);
  661.     octstr_delete(key_block, 0, bulk_table[wtls_machine->bulk_cipher_algorithm].key_material);
  662.     wtls_machine->server_write_IV = octstr_copy(key_block, 0, bulk_table[wtls_machine->bulk_cipher_algorithm].iv_size);
  663.     /* Additional calculations for exportable encryption algos */
  664.     if(bulk_table[wtls_machine->bulk_cipher_algorithm].is_exportable == EXPORTABLE) {
  665.         concatenatedRandoms = octstr_cat(wtls_machine->client_random, wtls_machine->server_random);
  666.         labelMaster = octstr_create("server write key");
  667.         final_server_write_enc_key = wtls_calculate_prf(wtls_machine->server_write_enc_key, labelMaster,
  668.                                                 concatenatedRandoms,
  669.                                                 bulk_table[wtls_machine->bulk_cipher_algorithm].key_material,
  670.                                                 wtls_machine);
  671.         octstr_destroy(labelMaster);
  672.         labelMaster = NULL;
  673.         octstr_destroy(concatenatedRandoms);
  674.         concatenatedRandoms = NULL;
  675.         octstr_destroy(wtls_machine->server_write_enc_key);
  676.         wtls_machine->server_write_enc_key = final_server_write_enc_key;
  677.         final_server_write_enc_key = NULL;
  678.         concatenatedRandoms = octstr_create("");
  679.         octstr_append_char(concatenatedRandoms, wtls_machine->server_seq_num);
  680.         octstr_append(concatenatedRandoms, wtls_machine->client_random);
  681.         octstr_append(concatenatedRandoms, wtls_machine->server_random);
  682.         emptySecret = octstr_create("");
  683.         final_server_write_IV = wtls_calculate_prf(emptySecret, labelMaster,
  684.                                 concatenatedRandoms,
  685.                                 bulk_table[wtls_machine->bulk_cipher_algorithm].iv_size,
  686.                                 wtls_machine);
  687.         octstr_destroy(labelMaster);
  688.         labelMaster = NULL;
  689.         octstr_destroy(concatenatedRandoms);
  690.         concatenatedRandoms = NULL;
  691.     }
  692. }
  693. void calculate_client_key_block(WTLSMachine *wtls_machine) {
  694.     Octstr* concatenatedRandoms=0;
  695.     Octstr* key_block;
  696.     Octstr* final_client_write_enc_key = NULL;
  697.     Octstr* final_client_write_IV = NULL;
  698.     Octstr* emptySecret = NULL;
  699.     Octstr* labelMaster=0;
  700.     /* Concatenate our random data */
  701.     concatenatedRandoms = octstr_create("");
  702.     pack_int16(concatenatedRandoms, 0,wtls_machine->client_seq_num);
  703.     octstr_append(concatenatedRandoms, wtls_machine->server_random);
  704.     octstr_append(concatenatedRandoms, wtls_machine->client_random);
  705.     /* Calculate the key_block */
  706.     labelMaster = octstr_create("client expansion");
  707.     key_block = wtls_calculate_prf(wtls_machine->master_secret, labelMaster,
  708.                                  concatenatedRandoms,
  709.                                  hash_table[wtls_machine->mac_algorithm].key_size
  710.                                  + bulk_table[wtls_machine->bulk_cipher_algorithm].key_material
  711.                                  + bulk_table[wtls_machine->bulk_cipher_algorithm].iv_size,
  712.                                  wtls_machine );
  713.     octstr_destroy(labelMaster);
  714.     labelMaster = NULL;
  715.     octstr_destroy(concatenatedRandoms);
  716.     concatenatedRandoms = NULL;
  717.     /* Break the key_block in its 3 parts */
  718.     wtls_machine->client_write_MAC_secret = octstr_copy(key_block, 0, hash_table[wtls_machine->mac_algorithm].key_size);
  719.     octstr_delete(key_block, 0, hash_table[wtls_machine->mac_algorithm].key_size);
  720.     wtls_machine->client_write_enc_key = octstr_copy(key_block, 0, bulk_table[wtls_machine->bulk_cipher_algorithm].key_material);
  721.     octstr_delete(key_block, 0, bulk_table[wtls_machine->bulk_cipher_algorithm].key_material);
  722.     wtls_machine->client_write_IV = octstr_copy(key_block, 0, bulk_table[wtls_machine->bulk_cipher_algorithm].iv_size);
  723.     /* Additional calculations for exportable encryption algos */
  724.     if(bulk_table[wtls_machine->bulk_cipher_algorithm].is_exportable == EXPORTABLE) {
  725.         concatenatedRandoms = octstr_cat(wtls_machine->client_random, wtls_machine->server_random);
  726.         labelMaster = octstr_create("client write key");
  727.         final_client_write_enc_key = wtls_calculate_prf(wtls_machine->client_write_enc_key, labelMaster,
  728.                                          concatenatedRandoms,
  729.                                          bulk_table[wtls_machine->bulk_cipher_algorithm].key_material,
  730.                                          wtls_machine);
  731.         octstr_destroy(labelMaster);
  732.         labelMaster = NULL;
  733.         octstr_destroy(wtls_machine->client_write_enc_key);
  734.         wtls_machine->client_write_enc_key = final_client_write_enc_key;
  735.         final_client_write_enc_key = NULL;
  736.         octstr_destroy(labelMaster);
  737.         labelMaster = NULL;
  738.         octstr_destroy(concatenatedRandoms);
  739.         concatenatedRandoms = NULL;
  740.         emptySecret = octstr_create("");
  741.         final_client_write_IV = wtls_calculate_prf(emptySecret, labelMaster,
  742.                                 concatenatedRandoms,
  743.                                 bulk_table[wtls_machine->bulk_cipher_algorithm].iv_size,
  744.                                 wtls_machine);
  745.         octstr_destroy(labelMaster);
  746.         labelMaster = NULL;
  747.         octstr_destroy(concatenatedRandoms);
  748.                         concatenatedRandoms = NULL;
  749.     }
  750. }
  751. #endif