| OLD | NEW |
| 1 diff --git a/lib/ssl/ssl.h b/lib/ssl/ssl.h | 1 diff --git a/lib/ssl/ssl.h b/lib/ssl/ssl.h |
| 2 index 120c257..eb7f7ec 100644 | 2 index 870a8cc..3550580 100644 |
| 3 --- a/lib/ssl/ssl.h | 3 --- a/lib/ssl/ssl.h |
| 4 +++ b/lib/ssl/ssl.h | 4 +++ b/lib/ssl/ssl.h |
| 5 @@ -385,6 +385,27 @@ SSL_IMPORT SECStatus SSL_DHEGroupPrefSet(PRFileDesc *fd, | 5 @@ -387,6 +387,27 @@ SSL_IMPORT SECStatus SSL_DHEGroupPrefSet(PRFileDesc *fd, |
| 6 */ | 6 */ |
| 7 SSL_IMPORT SECStatus SSL_EnableWeakDHEPrimeGroup(PRFileDesc *fd, PRBool enabled
); | 7 SSL_IMPORT SECStatus SSL_EnableWeakDHEPrimeGroup(PRFileDesc *fd, PRBool enabled
); |
| 8 | 8 |
| 9 +/* SSLChannelBindingType enumerates the types of supported channel binding | 9 +/* SSLChannelBindingType enumerates the types of supported channel binding |
| 10 + * values. See RFC 5929. */ | 10 + * values. See RFC 5929. */ |
| 11 +typedef enum SSLChannelBindingType { | 11 +typedef enum SSLChannelBindingType { |
| 12 + SSL_CHANNEL_BINDING_TLS_UNIQUE = 1, | 12 + SSL_CHANNEL_BINDING_TLS_UNIQUE = 1, |
| 13 +} SSLChannelBindingType; | 13 +} SSLChannelBindingType; |
| 14 + | 14 + |
| 15 +/* SSL_GetChannelBinding copies the requested channel binding value, as defined | 15 +/* SSL_GetChannelBinding copies the requested channel binding value, as defined |
| 16 + * in RFC 5929, into |out|. The full length of the binding value is written | 16 + * in RFC 5929, into |out|. The full length of the binding value is written |
| 17 + * into |*outLen|. | 17 + * into |*outLen|. |
| 18 + * | 18 + * |
| 19 + * At most |outLenMax| bytes of data are copied. If |outLenMax| is | 19 + * At most |outLenMax| bytes of data are copied. If |outLenMax| is |
| 20 + * insufficient then the function returns SECFailure and sets the error to | 20 + * insufficient then the function returns SECFailure and sets the error to |
| 21 + * SEC_ERROR_OUTPUT_LEN, but |*outLen| is still set. | 21 + * SEC_ERROR_OUTPUT_LEN, but |*outLen| is still set. |
| 22 + * | 22 + * |
| 23 + * This call will fail if made during a renegotiation. */ | 23 + * This call will fail if made during a renegotiation. */ |
| 24 +SSL_IMPORT SECStatus SSL_GetChannelBinding(PRFileDesc *fd, | 24 +SSL_IMPORT SECStatus SSL_GetChannelBinding(PRFileDesc *fd, |
| 25 +» » » » » SSLChannelBindingType binding_type, | 25 + SSLChannelBindingType binding_type, |
| 26 +» » » » » unsigned char *out, | 26 + unsigned char *out, |
| 27 +» » » » » unsigned int *outLen, | 27 + unsigned int *outLen, |
| 28 +» » » » » unsigned int outLenMax); | 28 + unsigned int outLenMax); |
| 29 + | 29 + |
| 30 /* SSL Version Range API | 30 /* SSL Version Range API |
| 31 ** | 31 ** |
| 32 ** This API should be used to control SSL 3.0 & TLS support instead of the | 32 ** This API should be used to control SSL 3.0 & TLS support instead of the |
| 33 diff --git a/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c | 33 diff --git a/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c |
| 34 index 2ae8ce9..ce92cf1 100644 | 34 index a2beec2..1394542 100644 |
| 35 --- a/lib/ssl/ssl3con.c | 35 --- a/lib/ssl/ssl3con.c |
| 36 +++ b/lib/ssl/ssl3con.c | 36 +++ b/lib/ssl/ssl3con.c |
| 37 @@ -13241,6 +13241,68 @@ ssl3_InitSocketPolicy(sslSocket *ss) | 37 @@ -13808,6 +13808,69 @@ ssl3_InitSocketPolicy(sslSocket *ss) |
| 38 ss->ssl3.signatureAlgorithmCount = PR_ARRAY_SIZE(defaultSignatureAlgorithms
); | 38 ss->ssl3.signatureAlgorithmCount = PR_ARRAY_SIZE(defaultSignatureAlgorithms
); |
| 39 } | 39 } |
| 40 | 40 |
| 41 +SECStatus | 41 +SECStatus |
| 42 +ssl3_GetTLSUniqueChannelBinding(sslSocket *ss, | 42 +ssl3_GetTLSUniqueChannelBinding(sslSocket *ss, |
| 43 +» » » » unsigned char *out, | 43 + unsigned char *out, |
| 44 +» » » » unsigned int *outLen, | 44 + unsigned int *outLen, |
| 45 +» » » » unsigned int outLenMax) { | 45 + unsigned int outLenMax) |
| 46 + PRBool isTLS; | 46 +{ |
| 47 + int index = 0; | 47 + PRBool isTLS; |
| 48 + int index = 0; |
| 48 + unsigned int len; | 49 + unsigned int len; |
| 49 + SECStatus rv = SECFailure; | 50 + SECStatus rv = SECFailure; |
| 50 + | 51 + |
| 51 + *outLen = 0; | 52 + *outLen = 0; |
| 52 + | 53 + |
| 53 + ssl_GetSSL3HandshakeLock(ss); | 54 + ssl_GetSSL3HandshakeLock(ss); |
| 54 + | 55 + |
| 55 + ssl_GetSpecReadLock(ss); | 56 + ssl_GetSpecReadLock(ss); |
| 56 + isTLS = (PRBool)(ss->ssl3.cwSpec->version > SSL_LIBRARY_VERSION_3_0); | 57 + isTLS = (PRBool)(ss->ssl3.cwSpec->version > SSL_LIBRARY_VERSION_3_0); |
| 57 + ssl_ReleaseSpecReadLock(ss); | 58 + ssl_ReleaseSpecReadLock(ss); |
| 58 + | 59 + |
| 59 + /* The tls-unique channel binding is the first Finished structure in the | 60 + /* The tls-unique channel binding is the first Finished structure in the |
| 60 + * handshake. In the case of a resumption, that's the server's Finished. | 61 + * handshake. In the case of a resumption, that's the server's Finished. |
| 61 + * Otherwise, it's the client's Finished. */ | 62 + * Otherwise, it's the client's Finished. */ |
| 62 + len = ss->ssl3.hs.finishedBytes; | 63 + len = ss->ssl3.hs.finishedBytes; |
| 63 + | 64 + |
| 64 + /* Sending or receiving a Finished message will set finishedBytes to a | 65 + /* Sending or receiving a Finished message will set finishedBytes to a |
| 65 + * non-zero value. */ | 66 + * non-zero value. */ |
| 66 + if (len == 0) { | 67 + if (len == 0) { |
| 67 +» PORT_SetError(SSL_ERROR_HANDSHAKE_NOT_COMPLETED); | 68 + PORT_SetError(SSL_ERROR_HANDSHAKE_NOT_COMPLETED); |
| 68 +» goto loser; | 69 + goto loser; |
| 69 + } | 70 + } |
| 70 + | 71 + |
| 71 + /* If we are in the middle of a renegotiation then the channel binding | 72 + /* If we are in the middle of a renegotiation then the channel binding |
| 72 + * value is poorly defined and depends on the direction that it will be | 73 + * value is poorly defined and depends on the direction that it will be |
| 73 + * used on. Therefore we simply return an error in this case. */ | 74 + * used on. Therefore we simply return an error in this case. */ |
| 74 + if (ss->firstHsDone && ss->ssl3.hs.ws != idle_handshake) { | 75 + if (ss->firstHsDone && ss->ssl3.hs.ws != idle_handshake) { |
| 75 +» PORT_SetError(SSL_ERROR_RENEGOTIATION_NOT_ALLOWED); | 76 + PORT_SetError(SSL_ERROR_RENEGOTIATION_NOT_ALLOWED); |
| 76 +» goto loser; | 77 + goto loser; |
| 77 + } | 78 + } |
| 78 + | 79 + |
| 79 + /* If resuming, then we want the second Finished value in the array, which | 80 + /* If resuming, then we want the second Finished value in the array, which |
| 80 + * is the server's */ | 81 + * is the server's */ |
| 81 + if (ss->ssl3.hs.isResuming) | 82 + if (ss->ssl3.hs.isResuming) |
| 82 +» index = 1; | 83 + index = 1; |
| 83 + | 84 + |
| 84 + *outLen = len; | 85 + *outLen = len; |
| 85 + if (outLenMax < len) { | 86 + if (outLenMax < len) { |
| 86 +» PORT_SetError(SEC_ERROR_OUTPUT_LEN); | 87 + PORT_SetError(SEC_ERROR_OUTPUT_LEN); |
| 87 +» goto loser; | 88 + goto loser; |
| 88 + } | 89 + } |
| 89 + | 90 + |
| 90 + if (isTLS) { | 91 + if (isTLS) { |
| 91 +» memcpy(out, &ss->ssl3.hs.finishedMsgs.tFinished[index], len); | 92 + memcpy(out, &ss->ssl3.hs.finishedMsgs.tFinished[index], len); |
| 92 + } else { | 93 + } else { |
| 93 +» memcpy(out, &ss->ssl3.hs.finishedMsgs.sFinished[index], len); | 94 + memcpy(out, &ss->ssl3.hs.finishedMsgs.sFinished[index], len); |
| 94 + } | 95 + } |
| 95 + | 96 + |
| 96 + rv = SECSuccess; | 97 + rv = SECSuccess; |
| 97 + | 98 + |
| 98 +loser: | 99 +loser: |
| 99 + ssl_ReleaseSSL3HandshakeLock(ss); | 100 + ssl_ReleaseSSL3HandshakeLock(ss); |
| 100 + return rv; | 101 + return rv; |
| 101 +} | 102 +} |
| 102 + | 103 + |
| 103 /* ssl3_config_match_init must have already been called by | 104 /* ssl3_config_match_init must have already been called by |
| 104 * the caller of this function. | 105 * the caller of this function. |
| 105 */ | 106 */ |
| 106 diff --git a/lib/ssl/sslimpl.h b/lib/ssl/sslimpl.h | 107 diff --git a/lib/ssl/sslimpl.h b/lib/ssl/sslimpl.h |
| 107 index c286518..976330e 100644 | 108 index 4607655..d47eb28 100644 |
| 108 --- a/lib/ssl/sslimpl.h | 109 --- a/lib/ssl/sslimpl.h |
| 109 +++ b/lib/ssl/sslimpl.h | 110 +++ b/lib/ssl/sslimpl.h |
| 110 @@ -1897,6 +1897,11 @@ extern PRBool ssl_GetSessionTicketKeysPKCS11(SECKEYPrivat
eKey *svrPrivKey, | 111 @@ -1981,6 +1981,11 @@ extern PRBool ssl_GetSessionTicketKeysPKCS11(SECKEYPrivat
eKey *svrPrivKey, |
| 111 extern SECStatus ssl3_ValidateNextProtoNego(const unsigned char* data, | 112 extern SECStatus ssl3_ValidateNextProtoNego(const unsigned char *data, |
| 112 » » » » » unsigned int length); | 113 unsigned int length); |
| 113 | 114 |
| 114 +extern SECStatus ssl3_GetTLSUniqueChannelBinding(sslSocket *ss, | 115 +extern SECStatus ssl3_GetTLSUniqueChannelBinding(sslSocket *ss, |
| 115 +» » » » » » unsigned char *out, | 116 + unsigned char *out, |
| 116 +» » » » » » unsigned int *outLen, | 117 + unsigned int *outLen, |
| 117 +» » » » » » unsigned int outLenMax); | 118 + unsigned int outLenMax); |
| 118 + | 119 + |
| 119 /* Construct a new NSPR socket for the app to use */ | 120 /* Construct a new NSPR socket for the app to use */ |
| 120 extern PRFileDesc *ssl_NewPRSocket(sslSocket *ss, PRFileDesc *fd); | 121 extern PRFileDesc *ssl_NewPRSocket(sslSocket *ss, PRFileDesc *fd); |
| 121 extern void ssl_FreePRSocket(PRFileDesc *fd); | 122 extern void ssl_FreePRSocket(PRFileDesc *fd); |
| 122 diff --git a/lib/ssl/sslsock.c b/lib/ssl/sslsock.c | 123 diff --git a/lib/ssl/sslsock.c b/lib/ssl/sslsock.c |
| 123 index efba686..c9a4493 100644 | 124 index 84c78b3..e312d82 100644 |
| 124 --- a/lib/ssl/sslsock.c | 125 --- a/lib/ssl/sslsock.c |
| 125 +++ b/lib/ssl/sslsock.c | 126 +++ b/lib/ssl/sslsock.c |
| 126 @@ -1540,6 +1540,28 @@ SSL_EnableWeakDHEPrimeGroup(PRFileDesc *fd, PRBool enable
d) | 127 @@ -1700,6 +1700,29 @@ SSL_EnableWeakDHEPrimeGroup(PRFileDesc *fd, PRBool enable
d) |
| 127 return SECSuccess; | 128 return SECSuccess; |
| 128 } | 129 } |
| 129 | 130 |
| 130 +SECStatus | 131 +SECStatus |
| 131 +SSL_GetChannelBinding(PRFileDesc *fd, | 132 +SSL_GetChannelBinding(PRFileDesc *fd, |
| 132 +» » SSLChannelBindingType binding_type, | 133 + SSLChannelBindingType binding_type, |
| 133 +» » unsigned char *out, | 134 + unsigned char *out, |
| 134 +» » unsigned int *outLen, | 135 + unsigned int *outLen, |
| 135 +» » unsigned int outLenMax) { | 136 + unsigned int outLenMax) |
| 137 +{ |
| 136 + sslSocket *ss = ssl_FindSocket(fd); | 138 + sslSocket *ss = ssl_FindSocket(fd); |
| 137 + | 139 + |
| 138 + if (!ss) { | 140 + if (!ss) { |
| 139 +» SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetChannelBinding", | 141 + SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetChannelBinding", |
| 140 +» » SSL_GETPID(), fd)); | 142 + SSL_GETPID(), fd)); |
| 141 +» return SECFailure; | 143 + return SECFailure; |
| 142 + } | 144 + } |
| 143 + | 145 + |
| 144 + if (binding_type != SSL_CHANNEL_BINDING_TLS_UNIQUE) { | 146 + if (binding_type != SSL_CHANNEL_BINDING_TLS_UNIQUE) { |
| 145 +» PORT_SetError(PR_INVALID_ARGUMENT_ERROR); | 147 + PORT_SetError(PR_INVALID_ARGUMENT_ERROR); |
| 146 +» return SECFailure; | 148 + return SECFailure; |
| 147 + } | 149 + } |
| 148 + | 150 + |
| 149 + return ssl3_GetTLSUniqueChannelBinding(ss, out, outLen, outLenMax); | 151 + return ssl3_GetTLSUniqueChannelBinding(ss, out, outLen, outLenMax); |
| 150 +} | 152 +} |
| 151 + | 153 + |
| 152 #include "dhe-param.c" | 154 #include "dhe-param.c" |
| 153 | 155 |
| 154 static const SSLDHEGroupType ssl_default_dhe_groups[] = { | 156 static const SSLDHEGroupType ssl_default_dhe_groups[] = { |
| OLD | NEW |