/* Snapshot is called by the receiver of the finished message to produce a hash of the preceeding handshake messages for comparison to incoming message. */ int32 sslSnapshotHSHash(ssl_t *ssl, unsigned char *out, int32 senderFlag) { sslMd5Context_t md5; sslSha1Context_t sha1; /* Use a backup of the message hash-to-date because we don't want to destroy the state of the handshaking until truly complete */ md5 = ssl->sec.msgHashMd5; sha1 = ssl->sec.msgHashSha1; return sslGenerateFinishedHash(&md5, &sha1, ssl->sec.masterSecret, out, senderFlag); }
/* Snapshot is called by the receiver of the finished message to produce a hash of the preceeding handshake messages for comparison to incoming message. */ int32 sslSnapshotHSHash(ssl_t *ssl, unsigned char *out, int32 senderFlag) { #ifdef USE_TLS psDigestContext_t sha256, sha384; #endif #ifndef USE_ONLY_TLS_1_2 psDigestContext_t md5, sha1; #endif int32 len = PS_FAILURE; /* Use a backup of the message hash-to-date because we don't want to destroy the state of the handshaking until truly complete */ #ifdef USE_TLS_1_2 if (ssl->flags & SSL_FLAGS_TLS_1_2) { sha256 = ssl->sec.msgHashSha256; #ifdef USE_SHA384 sha384 = ssl->sec.msgHashSha384; #endif } #endif #ifndef USE_ONLY_TLS_1_2 md5 = ssl->sec.msgHashMd5; sha1 = ssl->sec.msgHashSha1; #endif #ifdef USE_TLS if (ssl->flags & SSL_FLAGS_TLS) { #ifndef USE_ONLY_TLS_1_2 len = tlsGenerateFinishedHash(ssl, &md5, &sha1, &sha256, &sha384, ssl->sec.masterSecret, out, senderFlag); #else len = tlsGenerateFinishedHash(ssl, NULL, NULL, &sha256, &sha384, ssl->sec.masterSecret, out, senderFlag); #endif #ifndef DISABLE_SSLV3 } else { len = sslGenerateFinishedHash(&md5, &sha1, ssl->sec.masterSecret, out, senderFlag); #endif /* DISABLE_SSLV3 */ } #endif /* USE_TLS */ return len; }
sendClientFinished (sslStruct *sslC) { uchar buff[1024]; uchar plainText[256]; uchar verifyData[256]; uchar *p = &buff[0]; ushort length = 0; struct timeval tv; time_t curtime; uchar digest[16]; uchar sha1Hash[20]; int result; int i; // Record Hdr (Type, Version, Length) p[0] = handshake; //0x16 // TLS ver 1.2 uses version value 3.3 // SSL v3 is version 0300 p[1] = SSL_VERSION_1; p[2] = SSL_VERSION_2; PUT_BE16(&p[3], 0); // **** fill in this later at this point // current length, used by sendData, and also in pkt length = RECORD_HDR_LEN; // Note that we have done 5 bytes by now, which should be substracted // from the pkt length for the RecordProtocol. p[5] = finished; // 20 p[6] = 0; // 3rd MSByte of the Length, usualy 0 // length of Handshake pkt following length field = 1 byte PUT_BE16(&p[7], 0); // **** fill in this later at this point length = length + 4; // Calculate Master Secret // TLS1.0+ // Function call - tls1_prf() // master_secret = PRF(pre_master_secret, "master secret", // ClientHello.random + ServerHello.random) // Note: randoms are 32 bytes (include the timestamps) // sslC->masterSecret = PRF (sslC->preMasterSecret, "master secret", // sslC->random, sslC->serverRandom) // SSLv3 : Tested with openssl s_server and master_secret is correctly // generated. // Function: ssl3_generate_master_secret() // File: sslV3MasterSecret.c // master_secret = // MD5(pre_master_secret + SHA1('A' + pre_master_secret + randbytes)) + // MD5(pre_master_secret + SHA1('BB' + pre_master_secret + randbytes)) + // MD5(pre_master_secret + SHA1('CCC' + pre_master_secret + randbytes)) + { uchar *dest; dest = malloc(48); if (dest == NULL) { printf("\n Out of memory"); exit(1); } ssl3_generate_master_secret(sslC, dest, sslC->preMasterSecret, 48); printf("\n Master Secret "); for(i = 0; i <48; i++) printf("%02x ", dest[i]); memcpy(sslC->masterSecret, dest, 48); free(dest); }; // Calculate verify_data for Finished Msg - for SSLv3 // Sender: client = 0x434C4E54; server = 0x53525652 // md5_hash[16] = MD5(masterSecret + pad2 + // MD5(handshakeMsgs + Sender + masterSecret + pad1)); // sha_hash[20] = SHA(masterSecret + pad2 + // SHA(handshakeMsgs + Sender + masterSecret + pad1)); // m = MD5(sslC->handshakeMsgs) { uchar *out; out = malloc(36); sslC->clientHandshakeMsgs[sslC->clientHandshakeMsgsIndex] = '\0'; MD5_CTX md5_ctx; MD5_Init(&md5_ctx); MD5_Update(&md5_ctx, sslC->clientHandshakeMsgs, strlen(sslC->clientHandshakeMsgs)); printf("\n Length of Handshake Msgs sent by Client: %d", sslC->clientHandshakeMsgsIndex); SHA_CTX sha1_ctx; SHA1_Init(&sha1_ctx); SHA1_Update(&sha1_ctx, sslC->clientHandshakeMsgs, strlen(sslC->clientHandshakeMsgs)); sslGenerateFinishedHash(&md5_ctx, &sha1_ctx, sslC->masterSecret, out); memcpy(&p[9], out, 36); // TBD: The Finished message in hashed an encrypted. This currently // generates an error on the other side of - bad record MAC. // Need to use ssl3_setup_key_block and _generate_key_block routines free(out); } length += 36; // Finally fill in the lengths of Record and Handshake headers PUT_BE16(&p[3], length-RECORD_HDR_LEN); PUT_BE16(&p[7], length-RECORD_HDR_LEN-4); printf("\n-> Send Client Finished"); sendData(cfg.sslC, buff, length); }