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