update main-with-bazel from master branch
This commit is contained in:
+10
-13
@@ -3342,27 +3342,24 @@ OPENSSL_EXPORT const char *SSL_get_psk_identity(const SSL *ssl);
|
||||
//
|
||||
// *** EXPERIMENTAL — PRONE TO CHANGE ***
|
||||
//
|
||||
// draft-ietf-tls-subcerts is a proposed extension for TLS 1.3 and above that
|
||||
// allows an end point to use its certificate to delegate credentials for
|
||||
// authentication. If the peer indicates support for this extension, then this
|
||||
// host may use a delegated credential to sign the handshake. Once issued,
|
||||
// credentials can't be revoked. In order to mitigate the damage in case the
|
||||
// credential secret key is compromised, the credential is only valid for a
|
||||
// short time (days, hours, or even minutes). This library implements draft-03
|
||||
// of the protocol spec.
|
||||
// Delegated credentials (RFC 9345) allow a TLS 1.3 end point to use its
|
||||
// certificate to issue new credentials for authentication. If the peer
|
||||
// indicates support for this extension, then this host may use a delegated
|
||||
// credential to sign the handshake. Once issued, credentials can't be revoked.
|
||||
// In order to mitigate the damage in case the credential secret key is
|
||||
// compromised, the credential is only valid for a short time (days, hours, or
|
||||
// even minutes).
|
||||
//
|
||||
// The extension ID has not been assigned; we're using 0xff02 for the time
|
||||
// being. Currently only the server side is implemented.
|
||||
// Currently only the server side is implemented.
|
||||
//
|
||||
// Servers configure a DC for use in the handshake via
|
||||
// |SSL_set1_delegated_credential|. It must be signed by the host's end-entity
|
||||
// certificate as defined in draft-ietf-tls-subcerts-03.
|
||||
// certificate as defined in RFC 9345.
|
||||
|
||||
// SSL_set1_delegated_credential configures the delegated credential (DC) that
|
||||
// will be sent to the peer for the current connection. |dc| is the DC in wire
|
||||
// format, and |pkey| or |key_method| is the corresponding private key.
|
||||
// Currently (as of draft-03), only servers may configure a DC to use in the
|
||||
// handshake.
|
||||
// Currently, only servers may configure a DC to use in the handshake.
|
||||
//
|
||||
// The DC will only be used if the protocol version is correct and the signature
|
||||
// scheme is supported by the peer. If not, the DC will not be negotiated and
|
||||
|
||||
@@ -239,8 +239,8 @@ extern "C" {
|
||||
// ExtensionType value from RFC 5746
|
||||
#define TLSEXT_TYPE_renegotiate 0xff01
|
||||
|
||||
// ExtensionType value from draft-ietf-tls-subcerts.
|
||||
#define TLSEXT_TYPE_delegated_credential 0x22
|
||||
// ExtensionType value from RFC 9345
|
||||
#define TLSEXT_TYPE_delegated_credential 34
|
||||
|
||||
// ExtensionType value from draft-vvv-tls-alps. This is not an IANA defined
|
||||
// extension number.
|
||||
|
||||
@@ -2752,7 +2752,7 @@ static bool ext_quic_transport_params_add_serverhello_legacy(SSL_HANDSHAKE *hs,
|
||||
|
||||
// Delegated credentials.
|
||||
//
|
||||
// https://tools.ietf.org/html/draft-ietf-tls-subcerts
|
||||
// https://www.rfc-editor.org/rfc/rfc9345.html
|
||||
|
||||
static bool ext_delegated_credential_add_clienthello(
|
||||
const SSL_HANDSHAKE *hs, CBB *out, CBB *out_compressible,
|
||||
@@ -4122,7 +4122,7 @@ bool tls1_choose_signature_algorithm(SSL_HANDSHAKE *hs, uint16_t *out) {
|
||||
|
||||
Span<const uint16_t> sigalgs = kSignSignatureAlgorithms;
|
||||
if (ssl_signing_with_dc(hs)) {
|
||||
sigalgs = MakeConstSpan(&dc->expected_cert_verify_algorithm, 1);
|
||||
sigalgs = MakeConstSpan(&dc->dc_cert_verify_algorithm, 1);
|
||||
} else if (!cert->sigalgs.empty()) {
|
||||
sigalgs = cert->sigalgs;
|
||||
}
|
||||
|
||||
+4
-7
@@ -1574,8 +1574,7 @@ bool ssl_encrypt_client_hello(SSL_HANDSHAKE *hs, Span<const uint8_t> enc);
|
||||
|
||||
// Delegated credentials.
|
||||
|
||||
// This structure stores a delegated credential (DC) as defined by
|
||||
// draft-ietf-tls-subcerts-03.
|
||||
// This structure stores a delegated credential (DC) as defined by RFC 9345.
|
||||
struct DC {
|
||||
static constexpr bool kAllowUniquePtr = true;
|
||||
~DC();
|
||||
@@ -1588,13 +1587,11 @@ struct DC {
|
||||
// |*out_alert|.
|
||||
static UniquePtr<DC> Parse(CRYPTO_BUFFER *in, uint8_t *out_alert);
|
||||
|
||||
// raw is the delegated credential encoded as specified in draft-ietf-tls-
|
||||
// subcerts-03.
|
||||
// raw is the delegated credential encoded as specified in RFC 9345.
|
||||
UniquePtr<CRYPTO_BUFFER> raw;
|
||||
|
||||
// expected_cert_verify_algorithm is the signature scheme of the DC public
|
||||
// key.
|
||||
uint16_t expected_cert_verify_algorithm = 0;
|
||||
// dc_cert_verify_algorithm is the signature scheme of the DC public key.
|
||||
uint16_t dc_cert_verify_algorithm = 0;
|
||||
|
||||
// pkey is the public key parsed from |public_key|.
|
||||
UniquePtr<EVP_PKEY> pkey;
|
||||
|
||||
+4
-5
@@ -755,7 +755,7 @@ UniquePtr<DC> DC::Dup() {
|
||||
}
|
||||
|
||||
ret->raw = UpRef(raw);
|
||||
ret->expected_cert_verify_algorithm = expected_cert_verify_algorithm;
|
||||
ret->dc_cert_verify_algorithm = dc_cert_verify_algorithm;
|
||||
ret->pkey = UpRef(pkey);
|
||||
return ret;
|
||||
}
|
||||
@@ -775,7 +775,7 @@ UniquePtr<DC> DC::Parse(CRYPTO_BUFFER *in, uint8_t *out_alert) {
|
||||
uint16_t algorithm;
|
||||
CRYPTO_BUFFER_init_CBS(dc->raw.get(), &deleg);
|
||||
if (!CBS_get_u32(&deleg, &valid_time) ||
|
||||
!CBS_get_u16(&deleg, &dc->expected_cert_verify_algorithm) ||
|
||||
!CBS_get_u16(&deleg, &dc->dc_cert_verify_algorithm) ||
|
||||
!CBS_get_u24_length_prefixed(&deleg, &pubkey) ||
|
||||
!CBS_get_u16(&deleg, &algorithm) ||
|
||||
!CBS_get_u16_length_prefixed(&deleg, &sig) ||
|
||||
@@ -817,7 +817,7 @@ static bool ssl_can_serve_dc(const SSL_HANDSHAKE *hs) {
|
||||
// Check that the DC signature algorithm is supported by the peer.
|
||||
Span<const uint16_t> peer_sigalgs = hs->peer_delegated_credential_sigalgs;
|
||||
for (uint16_t peer_sigalg : peer_sigalgs) {
|
||||
if (dc->expected_cert_verify_algorithm == peer_sigalg) {
|
||||
if (dc->dc_cert_verify_algorithm == peer_sigalg) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -825,8 +825,7 @@ static bool ssl_can_serve_dc(const SSL_HANDSHAKE *hs) {
|
||||
}
|
||||
|
||||
bool ssl_signing_with_dc(const SSL_HANDSHAKE *hs) {
|
||||
// As of draft-ietf-tls-subcert-03, only the server may use delegated
|
||||
// credentials to authenticate itself.
|
||||
// We only support delegated credentials as a server.
|
||||
return hs->ssl->server &&
|
||||
hs->delegated_credential_requested &&
|
||||
ssl_can_serve_dc(hs);
|
||||
|
||||
@@ -110,6 +110,7 @@ const (
|
||||
extensionPadding uint16 = 21
|
||||
extensionExtendedMasterSecret uint16 = 23
|
||||
extensionCompressedCertAlgs uint16 = 27
|
||||
extensionDelegatedCredentials uint16 = 34
|
||||
extensionSessionTicket uint16 = 35
|
||||
extensionPreSharedKey uint16 = 41
|
||||
extensionEarlyData uint16 = 42
|
||||
@@ -127,7 +128,6 @@ const (
|
||||
extensionRenegotiationInfo uint16 = 0xff01
|
||||
extensionQUICTransportParamsLegacy uint16 = 0xffa5 // draft-ietf-quic-tls-32 and earlier
|
||||
extensionChannelID uint16 = 30032 // not IANA assigned
|
||||
extensionDelegatedCredentials uint16 = 0x22 // draft-ietf-tls-subcerts-06
|
||||
extensionDuplicate uint16 = 0xffff // not IANA assigned
|
||||
extensionEncryptedClientHello uint16 = 0xfe0d // not IANA assigned
|
||||
extensionECHOuterExtensions uint16 = 0xfd00 // not IANA assigned
|
||||
|
||||
@@ -1803,7 +1803,7 @@ func (hs *clientHandshakeState) doFullHandshake() error {
|
||||
// delegatedCredentialSignedMessage returns the bytes that are signed in order
|
||||
// to authenticate a delegated credential.
|
||||
func delegatedCredentialSignedMessage(credBytes []byte, algorithm signatureAlgorithm, leafDER []byte) []byte {
|
||||
// https://tools.ietf.org/html/draft-ietf-tls-subcerts-03#section-3
|
||||
// https://www.rfc-editor.org/rfc/rfc9345.html#section-4
|
||||
ret := make([]byte, 64, 128)
|
||||
for i := range ret {
|
||||
ret[i] = 0x20
|
||||
|
||||
@@ -1923,13 +1923,13 @@ type certificateEntry struct {
|
||||
}
|
||||
|
||||
type delegatedCredential struct {
|
||||
// https://tools.ietf.org/html/draft-ietf-tls-subcerts-03#section-3
|
||||
signedBytes []byte
|
||||
lifetimeSecs uint32
|
||||
expectedCertVerifyAlgo signatureAlgorithm
|
||||
pkixPublicKey []byte
|
||||
algorithm signatureAlgorithm
|
||||
signature []byte
|
||||
// https://www.rfc-editor.org/rfc/rfc9345.html#section-4
|
||||
signedBytes []byte
|
||||
lifetimeSecs uint32
|
||||
dcCertVerifyAlgo signatureAlgorithm
|
||||
pkixPublicKey []byte
|
||||
algorithm signatureAlgorithm
|
||||
signature []byte
|
||||
}
|
||||
|
||||
type certificateMsg struct {
|
||||
@@ -2030,17 +2030,17 @@ func (m *certificateMsg) unmarshal(data []byte) bool {
|
||||
case extensionSignedCertificateTimestamp:
|
||||
cert.sctList = []byte(body)
|
||||
case extensionDelegatedCredentials:
|
||||
// https://tools.ietf.org/html/draft-ietf-tls-subcerts-03#section-3
|
||||
// https://www.rfc-editor.org/rfc/rfc9345.html#section-4
|
||||
if cert.delegatedCredential != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
dc := new(delegatedCredential)
|
||||
origBody := body
|
||||
var expectedCertVerifyAlgo, algorithm uint16
|
||||
var dcCertVerifyAlgo, algorithm uint16
|
||||
|
||||
if !body.ReadUint32(&dc.lifetimeSecs) ||
|
||||
!body.ReadUint16(&expectedCertVerifyAlgo) ||
|
||||
!body.ReadUint16(&dcCertVerifyAlgo) ||
|
||||
!readUint24LengthPrefixedBytes(&body, &dc.pkixPublicKey) ||
|
||||
!body.ReadUint16(&algorithm) ||
|
||||
!readUint16LengthPrefixedBytes(&body, &dc.signature) ||
|
||||
@@ -2048,7 +2048,7 @@ func (m *certificateMsg) unmarshal(data []byte) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
dc.expectedCertVerifyAlgo = signatureAlgorithm(expectedCertVerifyAlgo)
|
||||
dc.dcCertVerifyAlgo = signatureAlgorithm(dcCertVerifyAlgo)
|
||||
dc.algorithm = signatureAlgorithm(algorithm)
|
||||
dc.signedBytes = []byte(origBody)[:4+2+3+len(dc.pkixPublicKey)]
|
||||
cert.delegatedCredential = dc
|
||||
|
||||
@@ -282,9 +282,9 @@ type delegatedCredentialConfig struct {
|
||||
// certificate, that the delegated credential is valid for. If zero, then 24
|
||||
// hours is assumed.
|
||||
lifetime time.Duration
|
||||
// expectedAlgo is the signature scheme that should be used with this
|
||||
// delegated credential. If zero, ECDSA with P-256 is assumed.
|
||||
expectedAlgo signatureAlgorithm
|
||||
// dcAlgo is the signature scheme that should be used with this delegated
|
||||
// credential. If zero, ECDSA with P-256 is assumed.
|
||||
dcAlgo signatureAlgorithm
|
||||
// tlsVersion is the version of TLS that should be used with this delegated
|
||||
// credential. If zero, TLS 1.3 is assumed.
|
||||
tlsVersion uint16
|
||||
@@ -320,14 +320,14 @@ func loadRSAPrivateKey(filename string) (priv *rsa.PrivateKey, privPKCS8 []byte,
|
||||
}
|
||||
|
||||
func createDelegatedCredential(config delegatedCredentialConfig, parentDER []byte, parentPriv crypto.PrivateKey) (dc, privPKCS8 []uint8, err error) {
|
||||
expectedAlgo := config.expectedAlgo
|
||||
if expectedAlgo == signatureAlgorithm(0) {
|
||||
expectedAlgo = signatureECDSAWithP256AndSHA256
|
||||
dcAlgo := config.dcAlgo
|
||||
if dcAlgo == signatureAlgorithm(0) {
|
||||
dcAlgo = signatureECDSAWithP256AndSHA256
|
||||
}
|
||||
|
||||
var pub crypto.PublicKey
|
||||
|
||||
switch expectedAlgo {
|
||||
switch dcAlgo {
|
||||
case signatureRSAPKCS1WithMD5, signatureRSAPKCS1WithSHA1, signatureRSAPKCS1WithSHA256, signatureRSAPKCS1WithSHA384, signatureRSAPKCS1WithSHA512, signatureRSAPSSWithSHA256, signatureRSAPSSWithSHA384, signatureRSAPSSWithSHA512:
|
||||
// RSA keys are expensive to generate so load from disk instead.
|
||||
var priv *rsa.PrivateKey
|
||||
@@ -339,7 +339,7 @@ func createDelegatedCredential(config delegatedCredentialConfig, parentDER []byt
|
||||
|
||||
case signatureECDSAWithSHA1, signatureECDSAWithP256AndSHA256, signatureECDSAWithP384AndSHA384, signatureECDSAWithP521AndSHA512:
|
||||
var curve elliptic.Curve
|
||||
switch expectedAlgo {
|
||||
switch dcAlgo {
|
||||
case signatureECDSAWithSHA1, signatureECDSAWithP256AndSHA256:
|
||||
curve = elliptic.P256()
|
||||
case signatureECDSAWithP384AndSHA384:
|
||||
@@ -362,7 +362,7 @@ func createDelegatedCredential(config delegatedCredentialConfig, parentDER []byt
|
||||
pub = &priv.PublicKey
|
||||
|
||||
default:
|
||||
return nil, nil, fmt.Errorf("unsupported expected signature algorithm: %x", expectedAlgo)
|
||||
return nil, nil, fmt.Errorf("unsupported DC signature algorithm: %x", dcAlgo)
|
||||
}
|
||||
|
||||
lifetime := config.lifetime
|
||||
@@ -382,9 +382,9 @@ func createDelegatedCredential(config delegatedCredentialConfig, parentDER []byt
|
||||
return nil, nil, fmt.Errorf("delegated credentials require TLS 1.3")
|
||||
}
|
||||
|
||||
// https://tools.ietf.org/html/draft-ietf-tls-subcerts-03#section-3
|
||||
// https://www.rfc-editor.org/rfc/rfc9345.html#section-4
|
||||
dc = append(dc, byte(lifetimeSecs>>24), byte(lifetimeSecs>>16), byte(lifetimeSecs>>8), byte(lifetimeSecs))
|
||||
dc = append(dc, byte(expectedAlgo>>8), byte(expectedAlgo))
|
||||
dc = append(dc, byte(dcAlgo>>8), byte(dcAlgo))
|
||||
|
||||
pubBytes, err := x509.MarshalPKIXPublicKey(pub)
|
||||
if err != nil {
|
||||
@@ -7490,7 +7490,7 @@ func addExtensionTests() {
|
||||
ApplicationSettings: map[string][]byte{"proto": []byte("runner2")},
|
||||
ALPSUseNewCodepoint: clientSends,
|
||||
},
|
||||
resumeSession: true,
|
||||
resumeSession: true,
|
||||
flags: append([]string{
|
||||
"-select-alpn", "proto",
|
||||
"-on-initial-application-settings", "proto,shim1",
|
||||
|
||||
Reference in New Issue
Block a user