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 + -
显示快捷键?