Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(659)

Unified Diff: net/third_party/nss/ssl/ssl3con.c

Issue 10424013: Support TLS Channel IDs in NSS (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: resync from trunk Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: net/third_party/nss/ssl/ssl3con.c
diff --git a/net/third_party/nss/ssl/ssl3con.c b/net/third_party/nss/ssl/ssl3con.c
index db9fad3dde5c2d84d4c14d7b0292f77a9ac743d2..6163bae8d52195a9fb33e7990a536b495efdc75b 100644
--- a/net/third_party/nss/ssl/ssl3con.c
+++ b/net/third_party/nss/ssl/ssl3con.c
@@ -86,6 +86,7 @@ static SECStatus ssl3_SendCertificate( sslSocket *ss);
static SECStatus ssl3_SendEmptyCertificate( sslSocket *ss);
static SECStatus ssl3_SendCertificateRequest(sslSocket *ss);
static SECStatus ssl3_SendNextProto( sslSocket *ss);
+static SECStatus ssl3_SendEncryptedExtensions(sslSocket *ss);
static SECStatus ssl3_SendFinished( sslSocket *ss, PRInt32 flags);
static SECStatus ssl3_SendServerHello( sslSocket *ss);
static SECStatus ssl3_SendServerHelloDone( sslSocket *ss);
@@ -6239,6 +6240,10 @@ ssl3_SendClientSecondRound(sslSocket *ss)
goto loser; /* err code was set. */
}
}
+ rv = ssl3_SendEncryptedExtensions(ss);
+ if (rv != SECSuccess) {
+ goto loser; /* err code was set. */
+ }
rv = ssl3_SendFinished(ss, 0);
if (rv != SECSuccess) {
@@ -8855,6 +8860,134 @@ ssl3_SendNextProto(sslSocket *ss)
return rv;
}
+/* called from ssl3_SendClientSecondRound
+ * ssl3_HandleFinished
+ */
+static SECStatus
+ssl3_SendEncryptedExtensions(sslSocket *ss)
+{
+ static const char CHANNEL_ID_MAGIC[] = "TLS Channel ID signature";
+ /* This is the ASN.1 prefix for a P-256 public key. Specifically it's:
+ * SEQUENCE
+ * SEQUENCE
+ * OID id-ecPublicKey
+ * OID prime256v1
+ * BIT STRING, length 66, 0 trailing bits: 0x04
+ *
+ * The 0x04 in the BIT STRING is the prefix for an uncompressed, X9.62
+ * public key. Following that are the two field elements as 32-byte,
+ * big-endian numbers, as required by the Channel ID. */
+ static const unsigned char P256_SPKI_PREFIX[] = {
+ 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86,
+ 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a,
+ 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03,
+ 0x42, 0x00, 0x04
+ };
+ /* ChannelIDs are always 128 bytes long: 64 bytes of P-256 public key and 64
+ * bytes of ECDSA signature. */
+ static const int CHANNEL_ID_PUBLIC_KEY_LENGTH = 64;
+ static const int CHANNEL_ID_LENGTH = 128;
+
+ SECStatus rv = SECFailure;
+ SECItem *spki = NULL;
+ SSL3Hashes hashes;
+ const unsigned char *pub_bytes;
+ unsigned char signed_data[sizeof(CHANNEL_ID_MAGIC) + sizeof(SSL3Hashes)];
+ unsigned char digest[SHA256_LENGTH];
+ SECItem digest_item;
+ unsigned char signature[64];
+ SECItem signature_item;
+ SECKEYPrivateKey *channelID = NULL;
+ SECKEYPublicKey *channelIDPub = NULL;
+
+ PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
+ PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
+
+ if (ss->ssl3.channelIDCallback == NULL ||
+ !ssl3_ExtensionNegotiated(ss, ssl_channel_id_xtn)) {
+ return SECSuccess;
+ }
+
+ rv = ss->ssl3.channelIDCallback(ss->ssl3.channelIDCallbackArg, ss->fd,
+ &channelIDPub, &channelID);
+ if (rv != SECSuccess) {
+ PORT_SetError(SSL_ERROR_CHANNEL_ID_CALLBACK_FAILED);
+ goto loser;
+ }
+
+ if (SECKEY_GetPrivateKeyType(channelID) != ecKey ||
+ PK11_SignatureLen(channelID) != sizeof(signature)) {
+ PORT_SetError(SSL_ERROR_INVALID_CHANNEL_ID_KEY);
+ rv = SECFailure;
+ goto loser;
+ }
+
+ ssl_GetSpecReadLock(ss);
+ rv = ssl3_ComputeHandshakeHashes(ss, ss->ssl3.cwSpec, &hashes, 0);
+ ssl_ReleaseSpecReadLock(ss);
+
+ if (rv != SECSuccess)
+ goto loser;
+
+ rv = ssl3_AppendHandshakeHeader(ss, encrypted_extensions,
+ 2 + 2 + CHANNEL_ID_LENGTH);
+ if (rv != SECSuccess)
+ goto loser; /* error code set by AppendHandshakeHeader */
+ rv = ssl3_AppendHandshakeNumber(ss, ssl_channel_id_xtn, 2);
+ if (rv != SECSuccess)
+ goto loser; /* error code set by AppendHandshake */
+ rv = ssl3_AppendHandshakeNumber(ss, CHANNEL_ID_LENGTH, 2);
+ if (rv != SECSuccess)
+ goto loser; /* error code set by AppendHandshake */
+
+ spki = SECKEY_EncodeDERSubjectPublicKeyInfo(channelIDPub);
+
+ if (spki->len != sizeof(P256_SPKI_PREFIX) + CHANNEL_ID_PUBLIC_KEY_LENGTH ||
+ memcmp(spki->data, P256_SPKI_PREFIX, sizeof(P256_SPKI_PREFIX) != 0)) {
+ PORT_SetError(SSL_ERROR_INVALID_CHANNEL_ID_KEY);
+ rv = SECFailure;
+ goto loser;
+ }
+
+ pub_bytes = spki->data + sizeof(P256_SPKI_PREFIX);
+
+ memcpy(signed_data, CHANNEL_ID_MAGIC, sizeof(CHANNEL_ID_MAGIC));
+ memcpy(signed_data + sizeof(CHANNEL_ID_MAGIC), &hashes, sizeof(hashes));
+
+ rv = PK11_HashBuf(SEC_OID_SHA256, digest, signed_data, sizeof(signed_data));
+ if (rv != SECSuccess)
+ goto loser;
+
+ digest_item.data = (void*) digest;
wtc 2012/05/31 00:36:32 Remove the (void*) casts here and on line 8964.
agl 2012/05/31 17:19:53 Done.
+ digest_item.len = sizeof(digest);
+
+ signature_item.data = (void*) signature;
+ signature_item.len = sizeof(signature);
+
+ rv = PK11_Sign(channelID, &signature_item, &digest_item);
+ if (rv != SECSuccess)
+ goto loser;
+
+ rv = ssl3_AppendHandshake(ss, pub_bytes, CHANNEL_ID_PUBLIC_KEY_LENGTH);
+ if (rv != SECSuccess)
+ goto loser;
+ rv = ssl3_AppendHandshake(ss, signature, sizeof(signature));
+ if (rv != SECSuccess)
+ goto loser;
+
+ rv = SECSuccess;
wtc 2012/05/31 00:36:32 Nit: lines 8975-8978 can be omitted because they a
agl 2012/05/31 17:19:53 Done.
+
+loser:
+ if (spki)
+ SECITEM_FreeItem(spki, PR_TRUE);
+ if (channelID)
+ SECKEY_DestroyPrivateKey(channelID);
+ if (channelIDPub)
+ SECKEY_DestroyPublicKey(channelIDPub);
+
+ return rv;
+}
+
/* called from ssl3_HandleServerHelloDone
* ssl3_HandleClientHello
* ssl3_HandleFinished
@@ -9105,11 +9238,16 @@ ssl3_HandleFinished(sslSocket *ss, SSL3Opaque *b, PRUint32 length,
flags = ssl_SEND_FLAG_FORCE_INTO_BUFFER;
}
- if (!isServer && !ss->firstHsDone) {
- rv = ssl3_SendNextProto(ss);
- if (rv != SECSuccess) {
- goto xmit_loser; /* err code was set. */
+ if (!isServer) {
+ if (!ss->firstHsDone) {
+ rv = ssl3_SendNextProto(ss);
+ if (rv != SECSuccess) {
+ goto xmit_loser; /* err code was set. */
+ }
}
+ rv = ssl3_SendEncryptedExtensions(ss);
+ if (rv != SECSuccess)
+ goto xmit_loser; /* err code was set. */
}
if (IS_DTLS(ss)) {

Powered by Google App Engine
This is Rietveld 408576698