write headers, handshake hash, mac, pad, and encrypt
| 279 | |
| 280 | // write headers, handshake hash, mac, pad, and encrypt |
| 281 | void cipherFinished(SSL& ssl, Finished& fin, output_buffer& output) |
| 282 | { |
| 283 | uint digestSz = ssl.getCrypto().get_digest().get_digestSize(); |
| 284 | uint finishedSz = ssl.isTLS() ? TLS_FINISHED_SZ : FINISHED_SZ; |
| 285 | uint sz = RECORD_HEADER + HANDSHAKE_HEADER + finishedSz + digestSz; |
| 286 | uint pad = 0; |
| 287 | uint blockSz = ssl.getCrypto().get_cipher().get_blockSize(); |
| 288 | |
| 289 | if (ssl.getSecurity().get_parms().cipher_type_ == block) { |
| 290 | if (ssl.isTLSv1_1()) |
| 291 | sz += blockSz; // IV |
| 292 | sz += 1; // pad byte |
| 293 | pad = (sz - RECORD_HEADER) % blockSz; |
| 294 | pad = blockSz - pad; |
| 295 | sz += pad; |
| 296 | } |
| 297 | |
| 298 | RecordLayerHeader rlHeader; |
| 299 | HandShakeHeader hsHeader; |
| 300 | buildHeaders(ssl, hsHeader, rlHeader, fin); |
| 301 | rlHeader.length_ = sz - RECORD_HEADER; // record header includes mac |
| 302 | // and pad, hanshake doesn't |
| 303 | input_buffer iv; |
| 304 | if (ssl.isTLSv1_1() && ssl.getSecurity().get_parms().cipher_type_== block){ |
| 305 | iv.allocate(blockSz); |
| 306 | ssl.getCrypto().get_random().Fill(iv.get_buffer(), blockSz); |
| 307 | iv.add_size(blockSz); |
| 308 | } |
| 309 | uint ivSz = iv.get_size(); |
| 310 | output.allocate(sz); |
| 311 | output << rlHeader << iv << hsHeader << fin; |
| 312 | |
| 313 | hashHandShake(ssl, output, ssl.isTLSv1_1() ? true : false); |
| 314 | opaque digest[SHA_LEN]; // max size |
| 315 | if (ssl.isTLS()) |
| 316 | TLS_hmac(ssl, digest, output.get_buffer() + RECORD_HEADER + ivSz, |
| 317 | output.get_size() - RECORD_HEADER - ivSz, handshake); |
| 318 | else |
| 319 | hmac(ssl, digest, output.get_buffer() + RECORD_HEADER, |
| 320 | output.get_size() - RECORD_HEADER, handshake); |
| 321 | output.write(digest, digestSz); |
| 322 | |
| 323 | if (ssl.getSecurity().get_parms().cipher_type_ == block) |
| 324 | for (uint i = 0; i <= pad; i++) output[AUTO] = pad; // pad byte gets |
| 325 | // pad value too |
| 326 | input_buffer cipher(rlHeader.length_); |
| 327 | ssl.useCrypto().use_cipher().encrypt(cipher.get_buffer(), |
| 328 | output.get_buffer() + RECORD_HEADER, output.get_size() - RECORD_HEADER); |
| 329 | output.set_current(RECORD_HEADER); |
| 330 | output.write(cipher.get_buffer(), cipher.get_capacity()); |
| 331 | } |
| 332 | |
| 333 | |
| 334 | // build an encrypted data or alert message for output |
no test coverage detected