ssl3con.c
来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 1,928 行 · 第 1/5 页
C
1,928 行
sha = PK11_CreateDigestContext(SEC_OID_SHA1); if (sha == NULL) { return rv; /* Caller must set hiLevel error code. */ } rv = PK11_DigestBegin(sha); rv |= PK11_DigestOp(sha, (unsigned char *)publicValue.data, publicValue.len); rv |= PK11_DigestFinal(sha, hash, &outLen, SHA1_LENGTH); PORT_Assert(rv != SECSuccess || outLen == SHA1_LENGTH); if (rv != SECSuccess) rv = SECFailure; PK11_DestroyContext(sha, PR_TRUE); return rv;}static voidssl3_BumpSequenceNumber(SSL3SequenceNumber *num){ num->low++; if (num->low == 0) num->high++;}/* Called only from ssl3_DestroyCipherSpec (immediately below). */static voidssl3_CleanupKeyMaterial(ssl3KeyMaterial *mat){ if (mat->write_key != NULL) { PK11_FreeSymKey(mat->write_key); mat->write_key = NULL; } if (mat->write_mac_key != NULL) { PK11_FreeSymKey(mat->write_mac_key); mat->write_mac_key = NULL; } if (mat->write_mac_context != NULL) { PK11_DestroyContext(mat->write_mac_context, PR_TRUE); mat->write_mac_context = NULL; }}/* Called from ssl3_SendChangeCipherSpecs() and ssl3_HandleChangeCipherSpecs()** Caller must hold SpecWriteLock.*/static voidssl3_DestroyCipherSpec(ssl3CipherSpec *spec){/* PORT_Assert( ssl_HaveSpecWriteLock(ss)); Don't have ss! */ if (spec->destroy) { spec->destroy(spec->encodeContext,PR_TRUE); spec->destroy(spec->decodeContext,PR_TRUE); spec->encodeContext = NULL; /* paranoia */ spec->decodeContext = NULL; } if (spec->master_secret != NULL) { PK11_FreeSymKey(spec->master_secret); spec->master_secret = NULL; } ssl3_CleanupKeyMaterial(&spec->client); ssl3_CleanupKeyMaterial(&spec->server); spec->destroy=NULL;}/* Called from ssl3_HandleServerHello(), ssl3_SendServerHello()** Caller must hold the ssl3 handshake lock.** Acquires & releases SpecWriteLock.*/static SECStatusssl3_SetupPendingCipherSpec(sslSocket *ss, ssl3State *ssl3){ ssl3CipherSpec * pwSpec; ssl3CipherSpec * cwSpec; ssl3CipherSuite suite = ssl3->hs.cipher_suite; sslSecurityInfo * sec = ss->sec; SSL3MACAlgorithm mac; SSL3BulkCipher cipher; SSL3KeyExchangeAlgorithm kea; const ssl3CipherSuiteDef *suite_def; PRBool isTLS; PORT_Assert( ssl_HaveSSL3HandshakeLock(ss)); ssl_GetSpecWriteLock(ss); /*******************************/ pwSpec = ssl3->pwSpec; PORT_Assert(pwSpec == ssl3->prSpec); /* This hack provides maximal interoperability with SSL 3 servers. */ cwSpec = ss->ssl3->cwSpec; if (cwSpec->mac_def->mac == mac_null) { /* SSL records are not being MACed. */ cwSpec->version = ss->version; } pwSpec->version = ss->version; isTLS = (PRBool)(pwSpec->version > SSL_LIBRARY_VERSION_3_0); SSL_TRC(3, ("%d: SSL3[%d]: Set XXX Pending Cipher Suite to 0x%04x", SSL_GETPID(), ss->fd, suite)); suite_def = ssl_LookupCipherSuiteDef(suite); if (suite_def == NULL) { ssl_ReleaseSpecWriteLock(ss); return SECFailure; /* error code set by ssl_LookupCipherSuiteDef */ } cipher = suite_def->bulk_cipher_alg; kea = suite_def->key_exchange_alg; mac = suite_def->mac_alg; if (isTLS) mac += 2; ssl3->hs.suite_def = suite_def; ssl3->hs.kea_def = &kea_defs[kea]; PORT_Assert(ssl3->hs.kea_def->kea == kea); pwSpec->cipher_def = &bulk_cipher_defs[cipher]; PORT_Assert(pwSpec->cipher_def->cipher == cipher); pwSpec->mac_def = &mac_defs[mac]; PORT_Assert(pwSpec->mac_def->mac == mac); sec->keyBits = pwSpec->cipher_def->key_size * BPB; sec->secretKeyBits = pwSpec->cipher_def->secret_key_size * BPB; sec->cipherType = cipher; pwSpec->encodeContext = NULL; pwSpec->decodeContext = NULL; pwSpec->mac_size = pwSpec->mac_def->mac_size; ssl_ReleaseSpecWriteLock(ss); /*******************************/ return SECSuccess;}/* * Called from: ssl3_SendClientKeyExchange (for Full handshake) * ssl3_HandleClientKeyExchange (for Full handshake) * ssl3_HandleServerHello (for session restart) * ssl3_HandleClientHello (for session restart) * Sets error code, but caller probably should override to disambiguate. * NULL pms means re-use old master_secret. */static SECStatusssl3_InitPendingCipherSpec(sslSocket *ss, PK11SymKey *pms){ ssl3CipherSpec * pwSpec; sslSecurityInfo * sec = ss->sec;const ssl3BulkCipherDef *cipher_def; PK11Context * serverContext = NULL; PK11Context * clientContext = NULL; SECItem * param; CK_ULONG macLength; SECStatus rv; CK_MECHANISM_TYPE mechanism; CK_MECHANISM_TYPE mac_mech; SECItem iv; SECItem mac_param; PORT_Assert( ssl_HaveSSL3HandshakeLock(ss)); ssl_GetSpecWriteLock(ss); /**************************************/ PORT_Assert(ss->ssl3->prSpec == ss->ssl3->pwSpec); pwSpec = ss->ssl3->pwSpec; cipher_def = pwSpec->cipher_def; macLength = pwSpec->mac_size; /* generate session keys from pms (if pms is not NULL) or ms */ rv = ssl3_GenerateSessionKeys(ss, pms); if (rv != SECSuccess) { goto bail_out; /* err code set by ssl3_GenerateSessionKeys */ } pwSpec->client.write_mac_context = NULL; pwSpec->server.write_mac_context = NULL; mac_param.data = (unsigned char *)&macLength; mac_param.len = sizeof(macLength); mac_mech = (CK_MECHANISM_TYPE) pwSpec->mac_def->malg; if (cipher_def->calg == calg_null) { pwSpec->encode = Null_Cipher; pwSpec->decode = Null_Cipher; pwSpec->destroy = NULL; pwSpec->client.write_mac_context = PK11_CreateContextBySymKey( mac_mech, CKA_SIGN, pwSpec->client.write_mac_key, &mac_param); if (pwSpec->client.write_mac_context == NULL) { ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE); goto fail; } pwSpec->server.write_mac_context = PK11_CreateContextBySymKey( mac_mech, CKA_SIGN, pwSpec->server.write_mac_key, &mac_param); if (pwSpec->server.write_mac_context == NULL) { ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE); goto fail; } goto success; } mechanism = (CK_MECHANISM_TYPE) cipher_def->calg; /* * build the server context */ iv.data = pwSpec->server.write_iv; iv.len = cipher_def->iv_size; param = PK11_ParamFromIV(mechanism, &iv); if (param == NULL) { ssl_MapLowLevelError(SSL_ERROR_IV_PARAM_FAILURE); goto fail; } serverContext = PK11_CreateContextBySymKey(mechanism, (sec->isServer ? CKA_ENCRYPT : CKA_DECRYPT), pwSpec->server.write_key, param); iv.data = PK11_IVFromParam(mechanism, param, (int *)&iv.len); if (iv.data) PORT_Memcpy(pwSpec->server.write_iv, iv.data, iv.len); SECITEM_FreeItem(param, PR_TRUE); if (serverContext == NULL) { ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE); goto fail; } /* * build the client context */ iv.data = pwSpec->client.write_iv; iv.len = cipher_def->iv_size; param = PK11_ParamFromIV(mechanism, &iv); if (param == NULL) { ssl_MapLowLevelError(SSL_ERROR_IV_PARAM_FAILURE); goto fail; } clientContext = PK11_CreateContextBySymKey(mechanism, (sec->isServer ? CKA_DECRYPT : CKA_ENCRYPT), pwSpec->client.write_key, param); iv.data = PK11_IVFromParam(mechanism, param, (int *)&iv.len); if (iv.data) PORT_Memcpy(pwSpec->client.write_iv, iv.data, iv.len); SECITEM_FreeItem(param,PR_TRUE); if (clientContext == NULL) { ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE); goto fail; } pwSpec->encodeContext = (sec->isServer) ? serverContext : clientContext; pwSpec->decodeContext = (sec->isServer) ? clientContext : serverContext; pwSpec->encode = (SSLCipher) PK11_CipherOp; pwSpec->decode = (SSLCipher) PK11_CipherOp; pwSpec->destroy = (SSLDestroy) PK11_DestroyContext; serverContext = NULL; clientContext = NULL; pwSpec->client.write_mac_context = PK11_CreateContextBySymKey( mac_mech,CKA_SIGN, pwSpec->client.write_mac_key,&mac_param); if (pwSpec->client.write_mac_context == NULL) { ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE); goto fail; } pwSpec->server.write_mac_context = PK11_CreateContextBySymKey( mac_mech, CKA_SIGN, pwSpec->server.write_mac_key,&mac_param); if (pwSpec->server.write_mac_context == NULL) { ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE); goto fail; }success: ssl_ReleaseSpecWriteLock(ss); /******************************/ return SECSuccess;fail: if (serverContext != NULL) PK11_DestroyContext(serverContext, PR_TRUE); if (clientContext != NULL) PK11_DestroyContext(clientContext, PR_TRUE); if (pwSpec->client.write_mac_context != NULL) { PK11_DestroyContext(pwSpec->client.write_mac_context,PR_TRUE); pwSpec->client.write_mac_context = NULL; } if (pwSpec->server.write_mac_context != NULL) { PK11_DestroyContext(pwSpec->server.write_mac_context,PR_TRUE); pwSpec->server.write_mac_context = NULL; }bail_out: ssl_ReleaseSpecWriteLock(ss); return SECFailure;}/* * 60 bytes is 3 times the maximum length MAC size that is supported. */static const unsigned char mac_pad_1 [60] = { 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36};static const unsigned char mac_pad_2 [60] = { 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c};/* Called from: ssl3_SendRecord()** ssl3_HandleRecord()** Caller must already hold the SpecReadLock. (wish we could assert that!)*/static SECStatusssl3_ComputeRecordMAC( ssl3CipherSpec * spec, PK11Context * mac_context, SSL3ContentType type, SSL3ProtocolVersion version, SSL3SequenceNumber seq_num, SSL3Opaque * input, int inputLength, unsigned char * outbuf, unsigned int * outLength){ const ssl3MACDef * mac_def; SECStatus rv; unsigned int tempLen; unsigned char temp[MAX_MAC_LENGTH];/* ssl_GetSpecReadLock(ss); Don't have "ss"! */ mac_def = spec->mac_def; if (mac_def->malg == malg_null) { *outLength = 0;/* ssl_ReleaseSpecReadLock(ss); */ return SECSuccess; } temp[0] = (unsigned char)(seq_num.high >> 24); temp[1] = (unsigned char)(seq_num.high >> 16); temp[2] = (unsigned char)(seq_num.high >> 8); temp[3] = (unsigned char)(seq_num.high >> 0); temp[4] = (unsigned char)(seq_num.low >> 24); temp[5] = (unsigned char)(seq_num.low >> 16); temp[6] = (unsigned char)(seq_num.low >> 8); temp[7] = (unsigned char)(seq_num.low >> 0); temp[8] = type; /* TLS MAC includes the record's version field, SSL's doesn't. ** We decide which MAC defintion to use based on the version of ** the protocol that was negotiated when the spec became current, ** NOT based on the version value in the record itself. ** But, we use the record'v version value in the computation. */ if (spec->version <= SSL_LIBRARY_VERSION_3_0) { temp[9] = MSB(inputLength); temp[10] = LSB(inputLength); tempLen = 11; } else { /* New TLS hash includes version. */ temp[9] = MSB(version); temp[10] = LSB(version); temp[11] = MSB(inputLength); temp[12] = LSB(inputLength); tempLen = 13; } PRINT_BUF(95, (NULL, "frag hash1: temp", temp, tempLen)); PRINT_BUF(95, (NULL, "frag hash1: input", input, inputLength)); rv = PK11_DigestBegin(mac_context); rv |= PK11_DigestOp(mac_context, temp, tempLen); rv |= PK11_DigestOp(mac_context, input, inputLength); rv |= PK11_DigestFinal(mac_context, outbuf, outLength, spec->mac_size); PORT_Assert(rv != SECSuccess || *outLength == (unsigned)spec->mac_size);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?