ssl3con.c

来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 1,928 行 · 第 1/5 页

C
1,928
字号
    SSL3KEAType               exchKeyType;    int                       i;    int                       numPresent		= 0;    int                       numEnabled		= 0;    PRBool                    isServer;    if (!ss->enableSSL3 && !ss->enableTLS) {    	return 0;    }    isServer = (PRBool)( ss && ss->sec && ss->sec->isServer );    for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) {	suite = &ss->cipherSuites[i];	if (suite->enabled) {	    ++numEnabled;	    /* We need the cipher defs to see if we have a token that can handle	     * this cipher.  It isn't part of the static definition.	     */	    cipher_def = ssl_LookupCipherSuiteDef(suite->cipher_suite);	    if (!cipher_def) {	    	suite->isPresent = PR_FALSE;		continue;	    }	    cipher_alg=bulk_cipher_defs[cipher_def->bulk_cipher_alg ].calg;	    exchKeyType =	    	    kea_defs[cipher_def->key_exchange_alg].exchKeyType;	    /* Mark the suites that are backed by real tokens, certs and keys */	    suite->isPresent = (PRBool)		(((exchKeyType == kt_null) ||		    (!isServer || (ss->serverKey[exchKeyType] &&				   ss->serverCertChain[exchKeyType])) &&		    PK11_TokenExists(kea_alg_defs[exchKeyType])) &&		((cipher_alg == calg_null) || PK11_TokenExists(cipher_alg)));	    if (suite->isPresent)	    	++numPresent;	}    }    PORT_Assert(numPresent > 0 || numEnabled == 0);    if (numPresent <= 0) {	PORT_SetError(SSL_ERROR_NO_CIPHERS_SUPPORTED);    }    return numPresent;}/* return PR_TRUE if suite matches policy and enabled state *//* It would be a REALLY BAD THING (tm) if we ever permitted the use** of a cipher that was NOT_ALLOWED.  So, if this is ever called with** policy == SSL_NOT_ALLOWED, report no match.*//* adjust suite enabled to the availability of a token that can do the * cipher suite. */static PRBoolconfig_match(ssl3CipherSuiteCfg *suite, int policy, PRBool enabled){    PORT_Assert(policy != SSL_NOT_ALLOWED && enabled != PR_FALSE);    if (policy == SSL_NOT_ALLOWED || !enabled)    	return PR_FALSE;    return (PRBool)(suite->enabled &&                    suite->isPresent &&	            suite->policy != SSL_NOT_ALLOWED &&		    suite->policy <= policy);}/* return number of cipher suites that match policy and enabled state *//* called from ssl3_SendClientHello and ssl3_ConstructV2CipherSpecsHack */static intcount_cipher_suites(sslSocket *ss, int policy, PRBool enabled){    int i, count = 0;    if (!ss->enableSSL3 && !ss->enableTLS) {    	return 0;    }    for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) {	if (config_match(&ss->cipherSuites[i], policy, enabled))	    count++;    }    if (count <= 0) {	PORT_SetError(SSL_ERROR_SSL_DISABLED);    }    return count;}static PRBoolanyRestrictedEnabled(sslSocket *ss){    int i;    if (!ss->enableSSL3 && !ss->enableTLS) {    	return PR_FALSE;    }    for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) {	ssl3CipherSuiteCfg *suite = &ss->cipherSuites[i];	if (suite->policy == SSL_RESTRICTED &&	    suite->enabled &&	    suite->isPresent)	    return PR_TRUE;    }    return PR_FALSE;}/* * Null compression, mac and encryption functions */static SECStatusNull_Cipher(void *ctx, unsigned char *output, int *outputLen, int maxOutputLen,	    const unsigned char *input, int inputLen){    *outputLen = inputLen;    if (input != output)	PORT_Memcpy(output, input, inputLen);    return SECSuccess;}/* * SSL3 Utility functions */SECStatusssl3_NegotiateVersion(sslSocket *ss, SSL3ProtocolVersion peerVersion){    SSL3ProtocolVersion version;    SSL3ProtocolVersion maxVersion;    if (ss->enableTLS) {	maxVersion = SSL_LIBRARY_VERSION_3_1_TLS;    } else if (ss->enableSSL3) {	maxVersion = SSL_LIBRARY_VERSION_3_0;    } else {    	/* what are we doing here? */	PORT_Assert(ss->enableSSL3 || ss->enableTLS);	PORT_SetError(SSL_ERROR_SSL_DISABLED);	return SECFailure;    }    ss->version = version = PR_MIN(maxVersion, peerVersion);    if ((version == SSL_LIBRARY_VERSION_3_1_TLS && ss->enableTLS) ||    	(version == SSL_LIBRARY_VERSION_3_0     && ss->enableSSL3)) {	return SECSuccess;    }    PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);    return SECFailure;}static SECStatusssl3_GetNewRandom(SSL3Random *random){    PRIntervalTime gmt = PR_IntervalToSeconds(PR_IntervalNow());    SECStatus rv;    random->rand[0] = (unsigned char)(gmt >> 24);    random->rand[1] = (unsigned char)(gmt >> 16);    random->rand[2] = (unsigned char)(gmt >>  8);    random->rand[3] = (unsigned char)(gmt);    /* first 4 bytes are reserverd for time */    rv = PK11_GenerateRandom(&random->rand[4], SSL3_RANDOM_LENGTH - 4);    if (rv != SECSuccess) {	ssl_MapLowLevelError(SSL_ERROR_GENERATE_RANDOM_FAILURE);    }    return rv;}static SECStatusssl3_SignHashes(SSL3Hashes *hash, SECKEYPrivateKey *key, SECItem *buf,                 PRBool isTLS){    SECStatus rv		= SECFailure;    PRBool    doDerEncode       = PR_FALSE;    int       signatureLen;    SECItem   hashItem;    buf->data    = NULL;    signatureLen = PK11_SignatureLen(key);    if (signatureLen <= 0) {	PORT_SetError(SEC_ERROR_INVALID_KEY);        goto done;    }    buf->len  = (unsigned)signatureLen;    buf->data = (unsigned char *)PORT_Alloc(signatureLen + 1);    if (!buf->data)        goto done;	/* error code was set. */    switch (key->keyType) {    case rsaKey:    	hashItem.data = hash->md5;    	hashItem.len = sizeof(SSL3Hashes);	break;    case dsaKey:    case fortezzaKey:	doDerEncode = isTLS;	hashItem.data = hash->sha;	hashItem.len = sizeof(hash->sha);	break;    default:	PORT_SetError(SEC_ERROR_INVALID_KEY);	goto done;    }    PRINT_BUF(60, (NULL, "hash(es) to be signed", hashItem.data, hashItem.len));    rv = PK11_Sign(key, buf, &hashItem);    if (rv != SECSuccess) {	ssl_MapLowLevelError(SSL_ERROR_SIGN_HASHES_FAILURE);    } else if (doDerEncode) {	SECItem   derSig	= {siBuffer, NULL, 0};    	rv = DSAU_EncodeDerSig(&derSig, buf);	if (rv == SECSuccess) {	    PORT_Free(buf->data);	/* discard unencoded signature. */	    *buf = derSig;		/* give caller encoded signature. */	} else if (derSig.data) {	    PORT_Free(derSig.data);	}    }    PRINT_BUF(60, (NULL, "signed hashes", (unsigned char*)buf->data, buf->len));done:    if (rv != SECSuccess && buf->data) {	PORT_Free(buf->data);	buf->data = NULL;    }    return rv;}static SECStatusssl3_VerifySignedHashes(SSL3Hashes *hash, CERTCertificate *cert,                         SECItem *buf, PRBool isTLS, void *pwArg){    SECKEYPublicKey * key;    SECItem *         signature	= NULL;    SECStatus         rv;    SECItem           hashItem;    PRINT_BUF(60, (NULL, "check signed hashes",                  buf->data, buf->len));    key = CERT_ExtractPublicKey(cert);    if (key == NULL) {	/* CERT_ExtractPublicKey doesn't set error code */	PORT_SetError(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE);    	return SECFailure;    }    switch (key->keyType) {    case rsaKey:    	hashItem.data = hash->md5;    	hashItem.len = sizeof(SSL3Hashes);	break;    case dsaKey:    case fortezzaKey:	hashItem.data = hash->sha;	hashItem.len = sizeof(hash->sha);	if (isTLS) {	    signature = DSAU_DecodeDerSig(buf);	    if (!signature) {	    	PORT_SetError(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);		return SECFailure;	    }	    buf = signature;	}	break;    default:    	SECKEY_DestroyPublicKey(key);	PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);	return SECFailure;    }    PRINT_BUF(60, (NULL, "hash(es) to be verified",                  hashItem.data, hashItem.len));    rv = PK11_Verify(key, buf, &hashItem, pwArg);    SECKEY_DestroyPublicKey(key);    if (signature) {    	SECITEM_FreeItem(signature, PR_TRUE);    }    if (rv != SECSuccess) {	ssl_MapLowLevelError(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);    }    return rv;}/* Caller must set hiLevel error code. */static SECStatusssl3_ComputeExportRSAKeyHash(SECItem modulus, SECItem publicExponent,			     SSL3Random *client_rand, SSL3Random *server_rand,			     SSL3Hashes *hashes){    PK11Context * md5 		= NULL;    PK11Context * sha 		= NULL;    PRUint8     * hashBuf;    PRUint8     * pBuf;    SECStatus     rv 		= SECSuccess;    unsigned int  outLen;    unsigned int  bufLen;    PRUint8       buf[2*SSL3_RANDOM_LENGTH + 2 + 4096/8 + 2 + 4096/8];    bufLen = 2*SSL3_RANDOM_LENGTH + 2 + modulus.len + 2 + publicExponent.len;    if (bufLen <= sizeof buf) {    	hashBuf = buf;    } else {    	hashBuf = PORT_Alloc(bufLen);	if (!hashBuf) {	    return SECFailure;	}    }    md5 = PK11_CreateDigestContext(SEC_OID_MD5);    if (md5 == NULL) {	ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);	rv = SECFailure; /* Caller must set hiLevel error code. */	goto done;    }    sha = PK11_CreateDigestContext(SEC_OID_SHA1);    if (sha == NULL) {	ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);	rv = SECFailure; /* Caller must set hiLevel error code. */	goto done;    }    memcpy(hashBuf, client_rand, SSL3_RANDOM_LENGTH);     	pBuf = hashBuf + SSL3_RANDOM_LENGTH;    memcpy(pBuf, server_rand, SSL3_RANDOM_LENGTH);    	pBuf += SSL3_RANDOM_LENGTH;    pBuf[0]  = (PRUint8)(modulus.len >> 8);    pBuf[1]  = (PRUint8)(modulus.len);    	pBuf += 2;    memcpy(pBuf, modulus.data, modulus.len);    	pBuf += modulus.len;    pBuf[0] = (PRUint8)(publicExponent.len >> 8);    pBuf[1] = (PRUint8)(publicExponent.len);    	pBuf += 2;    memcpy(pBuf, publicExponent.data, publicExponent.len);    	pBuf += publicExponent.len;    PORT_Assert(pBuf - hashBuf == bufLen);    rv  = PK11_DigestBegin(md5);    rv |= PK11_DigestOp(md5, hashBuf, bufLen);    rv |= PK11_DigestFinal(md5, hashes->md5, &outLen, MD5_LENGTH);    PORT_Assert(rv != SECSuccess || outLen == MD5_LENGTH);    if (rv != SECSuccess) {	ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);    	rv = SECFailure;	goto done;    }    rv  = PK11_DigestBegin(sha);    rv |= PK11_DigestOp(sha, hashBuf, bufLen);    rv |= PK11_DigestFinal(sha, hashes->sha, &outLen, SHA1_LENGTH);    PORT_Assert(rv != SECSuccess || outLen == SHA1_LENGTH);    if (rv != SECSuccess) {	ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);    	rv = SECFailure;	goto done;    }    PRINT_BUF(95, (NULL, "RSAkey hash: ", hashBuf, bufLen));    PRINT_BUF(95, (NULL, "RSAkey hash: MD5 result", hashes->md5, MD5_LENGTH));    PRINT_BUF(95, (NULL, "RSAkey hash: SHA1 result", hashes->sha, SHA1_LENGTH));done:    if (md5 != NULL) PK11_DestroyContext(md5, PR_TRUE);    if (sha != NULL) PK11_DestroyContext(sha, PR_TRUE);    if (hashBuf != buf && hashBuf != NULL)    	PORT_Free(hashBuf);    return rv;}/* Caller must set hiLevel error code. */static SECStatusssl3_ComputeFortezzaPublicKeyHash(SECItem publicValue, unsigned char * hash){    PK11Context *sha 	= NULL;    SECStatus    rv	= SECFailure;    unsigned int outLen;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?