mirror of
https://github.com/golang/go
synced 2024-11-25 15:47:56 -07:00
crypto/tls: Add support for ECDHE-ECDSA
Add support for ECDHE-ECDSA (RFC4492), which uses an ephemeral server key pair to perform ECDH with ECDSA signatures. Like ECDHE-RSA, ECDHE-ECDSA also provides PFS. R=agl CC=golang-dev https://golang.org/cl/7006047
This commit is contained in:
parent
85a7c090c4
commit
7b7dac5e23
@ -77,5 +77,8 @@ func RegisterHash(h Hash, f func() hash.Hash) {
|
|||||||
hashes[h] = f
|
hashes[h] = f
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PublicKey represents a public key using an unspecified algorithm.
|
||||||
|
type PublicKey interface{}
|
||||||
|
|
||||||
// PrivateKey represents a private key using an unspecified algorithm.
|
// PrivateKey represents a private key using an unspecified algorithm.
|
||||||
type PrivateKey interface{}
|
type PrivateKey interface{}
|
||||||
|
@ -55,8 +55,11 @@ var cipherSuites = []*cipherSuite{
|
|||||||
// Ciphersuite order is chosen so that ECDHE comes before plain RSA
|
// Ciphersuite order is chosen so that ECDHE comes before plain RSA
|
||||||
// and RC4 comes before AES (because of the Lucky13 attack).
|
// and RC4 comes before AES (because of the Lucky13 attack).
|
||||||
{TLS_ECDHE_RSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheRSAKA, true, cipherRC4, macSHA1},
|
{TLS_ECDHE_RSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheRSAKA, true, cipherRC4, macSHA1},
|
||||||
|
{TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheECDSAKA, true, cipherRC4, macSHA1},
|
||||||
{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheRSAKA, true, cipherAES, macSHA1},
|
{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheRSAKA, true, cipherAES, macSHA1},
|
||||||
|
{TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheECDSAKA, true, cipherAES, macSHA1},
|
||||||
{TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheRSAKA, true, cipherAES, macSHA1},
|
{TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheRSAKA, true, cipherAES, macSHA1},
|
||||||
|
{TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheECDSAKA, true, cipherAES, macSHA1},
|
||||||
{TLS_RSA_WITH_RC4_128_SHA, 16, 20, 0, rsaKA, false, cipherRC4, macSHA1},
|
{TLS_RSA_WITH_RC4_128_SHA, 16, 20, 0, rsaKA, false, cipherRC4, macSHA1},
|
||||||
{TLS_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, rsaKA, false, cipherAES, macSHA1},
|
{TLS_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, rsaKA, false, cipherAES, macSHA1},
|
||||||
{TLS_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, rsaKA, false, cipherAES, macSHA1},
|
{TLS_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, rsaKA, false, cipherAES, macSHA1},
|
||||||
@ -161,8 +164,16 @@ func rsaKA(version uint16) keyAgreement {
|
|||||||
return rsaKeyAgreement{}
|
return rsaKeyAgreement{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ecdheECDSAKA(version uint16) keyAgreement {
|
||||||
|
return &ecdheKeyAgreement{
|
||||||
|
sigType: signatureECDSA,
|
||||||
|
version: version,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func ecdheRSAKA(version uint16) keyAgreement {
|
func ecdheRSAKA(version uint16) keyAgreement {
|
||||||
return &ecdheRSAKeyAgreement{
|
return &ecdheKeyAgreement{
|
||||||
|
sigType: signatureRSA,
|
||||||
version: version,
|
version: version,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -186,12 +197,15 @@ func mutualCipherSuite(have []uint16, want uint16) *cipherSuite {
|
|||||||
// A list of the possible cipher suite ids. Taken from
|
// A list of the possible cipher suite ids. Taken from
|
||||||
// http://www.iana.org/assignments/tls-parameters/tls-parameters.xml
|
// http://www.iana.org/assignments/tls-parameters/tls-parameters.xml
|
||||||
const (
|
const (
|
||||||
TLS_RSA_WITH_RC4_128_SHA uint16 = 0x0005
|
TLS_RSA_WITH_RC4_128_SHA uint16 = 0x0005
|
||||||
TLS_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0x000a
|
TLS_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0x000a
|
||||||
TLS_RSA_WITH_AES_128_CBC_SHA uint16 = 0x002f
|
TLS_RSA_WITH_AES_128_CBC_SHA uint16 = 0x002f
|
||||||
TLS_RSA_WITH_AES_256_CBC_SHA uint16 = 0x0035
|
TLS_RSA_WITH_AES_256_CBC_SHA uint16 = 0x0035
|
||||||
TLS_ECDHE_RSA_WITH_RC4_128_SHA uint16 = 0xc011
|
TLS_ECDHE_ECDSA_WITH_RC4_128_SHA uint16 = 0xc007
|
||||||
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xc012
|
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA uint16 = 0xc009
|
||||||
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA uint16 = 0xc013
|
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA uint16 = 0xc00a
|
||||||
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA uint16 = 0xc014
|
TLS_ECDHE_RSA_WITH_RC4_128_SHA uint16 = 0xc011
|
||||||
|
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xc012
|
||||||
|
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA uint16 = 0xc013
|
||||||
|
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA uint16 = 0xc014
|
||||||
)
|
)
|
||||||
|
@ -9,6 +9,7 @@ import (
|
|||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"io"
|
"io"
|
||||||
|
"math/big"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
@ -98,6 +99,12 @@ const (
|
|||||||
certTypeDSSSign = 2 // A certificate containing a DSA key
|
certTypeDSSSign = 2 // A certificate containing a DSA key
|
||||||
certTypeRSAFixedDH = 3 // A certificate containing a static DH key
|
certTypeRSAFixedDH = 3 // A certificate containing a static DH key
|
||||||
certTypeDSSFixedDH = 4 // A certificate containing a static DH key
|
certTypeDSSFixedDH = 4 // A certificate containing a static DH key
|
||||||
|
|
||||||
|
// See RFC4492 sections 3 and 5.5.
|
||||||
|
certTypeECDSASign = 64 // A certificate containing an ECDSA-capable public key, signed with ECDSA.
|
||||||
|
certTypeRSAFixedECDH = 65 // A certificate containing an ECDH-capable public key, signed with RSA.
|
||||||
|
certTypeECDSAFixedECDH = 66 // A certificate containing an ECDH-capable public key, signed with ECDSA.
|
||||||
|
|
||||||
// Rest of these are reserved by the TLS spec
|
// Rest of these are reserved by the TLS spec
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -120,10 +127,11 @@ type signatureAndHash struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// supportedSignatureAlgorithms contains the signature and hash algorithms that
|
// supportedSignatureAlgorithms contains the signature and hash algorithms that
|
||||||
// the code will adverse as supported both in a TLS 1.2 ClientHello and
|
// the code can advertise as supported both in a TLS 1.2 ClientHello and
|
||||||
// CertificateRequest.
|
// CertificateRequest.
|
||||||
var supportedSignatureAlgorithms = []signatureAndHash{
|
var supportedSignatureAlgorithms = []signatureAndHash{
|
||||||
{hashSHA256, signatureRSA},
|
{hashSHA256, signatureRSA},
|
||||||
|
{hashSHA256, signatureECDSA},
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConnectionState records basic TLS details about the connection.
|
// ConnectionState records basic TLS details about the connection.
|
||||||
@ -372,7 +380,7 @@ func (c *Config) BuildNameToCertificate() {
|
|||||||
// A Certificate is a chain of one or more certificates, leaf first.
|
// A Certificate is a chain of one or more certificates, leaf first.
|
||||||
type Certificate struct {
|
type Certificate struct {
|
||||||
Certificate [][]byte
|
Certificate [][]byte
|
||||||
PrivateKey crypto.PrivateKey // supported types: *rsa.PrivateKey
|
PrivateKey crypto.PrivateKey // supported types: *rsa.PrivateKey, *ecdsa.PrivateKey
|
||||||
// OCSPStaple contains an optional OCSP response which will be served
|
// OCSPStaple contains an optional OCSP response which will be served
|
||||||
// to clients that request it.
|
// to clients that request it.
|
||||||
OCSPStaple []byte
|
OCSPStaple []byte
|
||||||
@ -395,6 +403,13 @@ type handshakeMessage interface {
|
|||||||
unmarshal([]byte) bool
|
unmarshal([]byte) bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(jsing): Make these available to both crypto/x509 and crypto/tls.
|
||||||
|
type dsaSignature struct {
|
||||||
|
R, S *big.Int
|
||||||
|
}
|
||||||
|
|
||||||
|
type ecdsaSignature dsaSignature
|
||||||
|
|
||||||
var emptyConfig Config
|
var emptyConfig Config
|
||||||
|
|
||||||
func defaultConfig() *Config {
|
func defaultConfig() *Config {
|
||||||
|
@ -6,9 +6,11 @@ package tls
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"crypto/ecdsa"
|
||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
"crypto/subtle"
|
"crypto/subtle"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
|
"encoding/asn1"
|
||||||
"errors"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"strconv"
|
"strconv"
|
||||||
@ -124,7 +126,10 @@ func (c *Conn) clientHandshake() error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, ok := certs[0].PublicKey.(*rsa.PublicKey); !ok {
|
switch certs[0].PublicKey.(type) {
|
||||||
|
case *rsa.PublicKey, *ecdsa.PublicKey:
|
||||||
|
break
|
||||||
|
default:
|
||||||
return c.sendAlert(alertUnsupportedCertificate)
|
return c.sendAlert(alertUnsupportedCertificate)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,12 +192,13 @@ func (c *Conn) clientHandshake() error {
|
|||||||
|
|
||||||
finishedHash.Write(certReq.marshal())
|
finishedHash.Write(certReq.marshal())
|
||||||
|
|
||||||
// For now, we only know how to sign challenges with RSA
|
var rsaAvail, ecdsaAvail bool
|
||||||
rsaAvail := false
|
|
||||||
for _, certType := range certReq.certificateTypes {
|
for _, certType := range certReq.certificateTypes {
|
||||||
if certType == certTypeRSASign {
|
switch certType {
|
||||||
|
case certTypeRSASign:
|
||||||
rsaAvail = true
|
rsaAvail = true
|
||||||
break
|
case certTypeECDSASign:
|
||||||
|
ecdsaAvail = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -201,7 +207,7 @@ func (c *Conn) clientHandshake() error {
|
|||||||
// certReq.certificateAuthorities
|
// certReq.certificateAuthorities
|
||||||
findCert:
|
findCert:
|
||||||
for i, chain := range c.config.Certificates {
|
for i, chain := range c.config.Certificates {
|
||||||
if !rsaAvail {
|
if !rsaAvail && !ecdsaAvail {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,7 +222,10 @@ func (c *Conn) clientHandshake() error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if x509Cert.PublicKeyAlgorithm != x509.RSA {
|
switch {
|
||||||
|
case rsaAvail && x509Cert.PublicKeyAlgorithm == x509.RSA:
|
||||||
|
case ecdsaAvail && x509Cert.PublicKeyAlgorithm == x509.ECDSA:
|
||||||
|
default:
|
||||||
continue findCert
|
continue findCert
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -271,9 +280,21 @@ func (c *Conn) clientHandshake() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if chainToSend != nil {
|
if chainToSend != nil {
|
||||||
|
var signed []byte
|
||||||
certVerify := new(certificateVerifyMsg)
|
certVerify := new(certificateVerifyMsg)
|
||||||
digest, hashFunc := finishedHash.hashForClientCertificate()
|
switch key := c.config.Certificates[0].PrivateKey.(type) {
|
||||||
signed, err := rsa.SignPKCS1v15(c.config.rand(), c.config.Certificates[0].PrivateKey.(*rsa.PrivateKey), hashFunc, digest)
|
case *ecdsa.PrivateKey:
|
||||||
|
digest, _ := finishedHash.hashForClientCertificate(signatureECDSA)
|
||||||
|
r, s, err := ecdsa.Sign(c.config.rand(), key, digest)
|
||||||
|
if err == nil {
|
||||||
|
signed, err = asn1.Marshal(ecdsaSignature{r, s})
|
||||||
|
}
|
||||||
|
case *rsa.PrivateKey:
|
||||||
|
digest, hashFunc := finishedHash.hashForClientCertificate(signatureRSA)
|
||||||
|
signed, err = rsa.SignPKCS1v15(c.config.rand(), key, hashFunc, digest)
|
||||||
|
default:
|
||||||
|
err = errors.New("unknown private key type")
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.sendAlert(alertInternalError)
|
return c.sendAlert(alertInternalError)
|
||||||
}
|
}
|
||||||
|
@ -39,16 +39,24 @@ func testClientScript(t *testing.T, name string, clientScript [][]byte, config *
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHandshakeClientRC4(t *testing.T) {
|
func TestHandshakeClientRSARC4(t *testing.T) {
|
||||||
var config = *testConfig
|
var config = *testConfig
|
||||||
config.CipherSuites = []uint16{TLS_RSA_WITH_RC4_128_SHA}
|
config.CipherSuites = []uint16{TLS_RSA_WITH_RC4_128_SHA}
|
||||||
testClientScript(t, "RC4", rc4ClientScript, &config)
|
testClientScript(t, "RSA-RC4", rsaRC4ClientScript, &config)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHandshakeClientECDHEAES(t *testing.T) {
|
func TestHandshakeClientECDHERSAAES(t *testing.T) {
|
||||||
var config = *testConfig
|
var config = *testConfig
|
||||||
config.CipherSuites = []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA}
|
config.CipherSuites = []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA}
|
||||||
testClientScript(t, "ECDHE-AES", ecdheAESClientScript, &config)
|
testClientScript(t, "ECDHE-RSA-AES", ecdheRSAAESClientScript, &config)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHandshakeClientECDHECDSAAES(t *testing.T) {
|
||||||
|
var config = *testConfig
|
||||||
|
config.CipherSuites = []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA}
|
||||||
|
config.Certificates = nil
|
||||||
|
config.BuildNameToCertificate()
|
||||||
|
testClientScript(t, "ECDHE-ECDSA-AES", ecdheECDSAAESClientScript, &config)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestLongClientCerticiateChain(t *testing.T) {
|
func TestLongClientCerticiateChain(t *testing.T) {
|
||||||
@ -175,7 +183,7 @@ func TestEmptyRecords(t *testing.T) {
|
|||||||
// CSqGSIb3DQEBBQUAA0EAhTZAc8G7GtrUWZ8tonAxRnTsg26oyDxRrzms7EC86CJG
|
// CSqGSIb3DQEBBQUAA0EAhTZAc8G7GtrUWZ8tonAxRnTsg26oyDxRrzms7EC86CJG
|
||||||
// HZnWRiok1IsFCEv7NRFukrt3uuQSu/TIXpyBqJdgTA==
|
// HZnWRiok1IsFCEv7NRFukrt3uuQSu/TIXpyBqJdgTA==
|
||||||
// -----END CERTIFICATE-----
|
// -----END CERTIFICATE-----
|
||||||
var rc4ClientScript = [][]byte{
|
var rsaRC4ClientScript = [][]byte{
|
||||||
{
|
{
|
||||||
0x16, 0x03, 0x01, 0x00, 0x4a, 0x01, 0x00, 0x00,
|
0x16, 0x03, 0x01, 0x00, 0x4a, 0x01, 0x00, 0x00,
|
||||||
0x46, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x46, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
@ -296,7 +304,7 @@ var rc4ClientScript = [][]byte{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var ecdheAESClientScript = [][]byte{
|
var ecdheRSAAESClientScript = [][]byte{
|
||||||
{
|
{
|
||||||
0x16, 0x03, 0x01, 0x00, 0x4a, 0x01, 0x00, 0x00,
|
0x16, 0x03, 0x01, 0x00, 0x4a, 0x01, 0x00, 0x00,
|
||||||
0x46, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x46, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
@ -1811,265 +1819,178 @@ var clientChainCertificateScript = [][]byte{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// $ openssl s_server -tls1_2 -cert server.crt -key server.key \
|
||||||
|
// -cipher ECDHE-RSA-AES128-SHA -port 10443
|
||||||
|
// $ go test -test.run "TestRunClient" -connect -ciphersuites=0xc013 \
|
||||||
|
// -minversion=0x0303 -maxversion=0x0303
|
||||||
var clientTLS12Script = [][]byte{
|
var clientTLS12Script = [][]byte{
|
||||||
{
|
{
|
||||||
0x16, 0x03, 0x01, 0x00, 0x52, 0x01, 0x00, 0x00,
|
0x16, 0x03, 0x01, 0x00, 0x54, 0x01, 0x00, 0x00,
|
||||||
0x4e, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x50, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xc0, 0x13,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xc0, 0x13,
|
||||||
0x01, 0x00, 0x00, 0x23, 0x00, 0x05, 0x00, 0x05,
|
0x01, 0x00, 0x00, 0x25, 0x00, 0x05, 0x00, 0x05,
|
||||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00,
|
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00,
|
||||||
0x08, 0x00, 0x06, 0x00, 0x17, 0x00, 0x18, 0x00,
|
0x08, 0x00, 0x06, 0x00, 0x17, 0x00, 0x18, 0x00,
|
||||||
0x19, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
|
0x19, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
|
||||||
0x0d, 0x00, 0x04, 0x00, 0x02, 0x04, 0x01,
|
0x0d, 0x00, 0x06, 0x00, 0x04, 0x04, 0x01, 0x04,
|
||||||
|
0x03,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
0x16, 0x03, 0x03, 0x00, 0x54, 0x02, 0x00, 0x00,
|
0x16, 0x03, 0x03, 0x00, 0x54, 0x02, 0x00, 0x00,
|
||||||
0x50, 0x03, 0x03, 0x51, 0xcd, 0xe6, 0x5e, 0x4c,
|
0x50, 0x03, 0x03, 0x51, 0xe5, 0x78, 0x4c, 0x64,
|
||||||
0x36, 0x2f, 0xe1, 0x38, 0x6c, 0xff, 0x9c, 0xe2,
|
0x66, 0xd0, 0xee, 0x0b, 0x8b, 0xfd, 0x9b, 0xe0,
|
||||||
0x0f, 0xbb, 0x04, 0x6d, 0x82, 0xa6, 0x1a, 0x85,
|
0x54, 0x3c, 0x6e, 0x05, 0x04, 0x2f, 0x77, 0x07,
|
||||||
0xfa, 0x8c, 0x04, 0xb7, 0xcb, 0xcc, 0x39, 0x02,
|
0x8c, 0x04, 0xb9, 0xf6, 0xdd, 0xea, 0x1a, 0x7c,
|
||||||
0xb3, 0x24, 0xff, 0x20, 0xaa, 0x79, 0xb0, 0x04,
|
0xdf, 0x65, 0x39, 0x20, 0xea, 0xa2, 0xef, 0x53,
|
||||||
0x70, 0x39, 0x7a, 0x3b, 0xd7, 0xe0, 0x16, 0x43,
|
0x96, 0xf5, 0x0b, 0x8a, 0x47, 0xa0, 0x7c, 0x20,
|
||||||
0x63, 0xd2, 0x04, 0xc9, 0x4a, 0x49, 0x08, 0xf8,
|
0x53, 0x75, 0xee, 0x87, 0xb9, 0xd3, 0xe2, 0xa6,
|
||||||
0x1c, 0xf6, 0xba, 0x5f, 0xe2, 0x61, 0x8c, 0xa4,
|
0x97, 0x64, 0xb9, 0xa6, 0xcc, 0xc0, 0xe5, 0xbf,
|
||||||
0x3d, 0x81, 0x6a, 0x79, 0xc0, 0x13, 0x00, 0x00,
|
0x92, 0x1d, 0xee, 0x4d, 0xc0, 0x13, 0x00, 0x00,
|
||||||
0x08, 0x00, 0x0b, 0x00, 0x04, 0x03, 0x00, 0x01,
|
0x08, 0x00, 0x0b, 0x00, 0x04, 0x03, 0x00, 0x01,
|
||||||
0x02, 0x16, 0x03, 0x03, 0x03, 0xf5, 0x0b, 0x00,
|
0x02, 0x16, 0x03, 0x03, 0x02, 0x39, 0x0b, 0x00,
|
||||||
0x03, 0xf1, 0x00, 0x03, 0xee, 0x00, 0x03, 0xeb,
|
0x02, 0x35, 0x00, 0x02, 0x32, 0x00, 0x02, 0x2f,
|
||||||
0x30, 0x82, 0x03, 0xe7, 0x30, 0x82, 0x02, 0xcf,
|
0x30, 0x82, 0x02, 0x2b, 0x30, 0x82, 0x01, 0xd5,
|
||||||
0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x09, 0x00,
|
0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x09, 0x00,
|
||||||
0xb9, 0xee, 0xd4, 0xd9, 0x55, 0xa5, 0x9e, 0xb3,
|
0xb1, 0x35, 0x13, 0x65, 0x11, 0x20, 0xc5, 0x92,
|
||||||
0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
|
0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
|
||||||
0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30,
|
0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30,
|
||||||
0x70, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
|
0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
|
||||||
0x04, 0x06, 0x13, 0x02, 0x55, 0x4b, 0x31, 0x16,
|
0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13,
|
||||||
0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c,
|
0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13,
|
||||||
0x0d, 0x4f, 0x70, 0x65, 0x6e, 0x53, 0x53, 0x4c,
|
0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74,
|
||||||
0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x31, 0x22,
|
0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06,
|
||||||
0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c,
|
0x03, 0x55, 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e,
|
||||||
0x19, 0x46, 0x4f, 0x52, 0x20, 0x54, 0x45, 0x53,
|
0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57,
|
||||||
0x54, 0x49, 0x4e, 0x47, 0x20, 0x50, 0x55, 0x52,
|
0x69, 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50,
|
||||||
0x50, 0x4f, 0x53, 0x45, 0x53, 0x20, 0x4f, 0x4e,
|
0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x30, 0x1e,
|
||||||
0x4c, 0x59, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03,
|
0x17, 0x0d, 0x31, 0x32, 0x30, 0x34, 0x30, 0x36,
|
||||||
0x55, 0x04, 0x03, 0x0c, 0x1c, 0x4f, 0x70, 0x65,
|
0x31, 0x37, 0x31, 0x30, 0x31, 0x33, 0x5a, 0x17,
|
||||||
0x6e, 0x53, 0x53, 0x4c, 0x20, 0x54, 0x65, 0x73,
|
0x0d, 0x31, 0x35, 0x30, 0x34, 0x30, 0x36, 0x31,
|
||||||
0x74, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6d,
|
0x37, 0x31, 0x30, 0x31, 0x33, 0x5a, 0x30, 0x45,
|
||||||
0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x20, 0x43,
|
0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
|
||||||
0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x31, 0x31,
|
0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30,
|
||||||
0x32, 0x30, 0x38, 0x31, 0x34, 0x30, 0x31, 0x34,
|
0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a,
|
||||||
0x38, 0x5a, 0x17, 0x0d, 0x32, 0x31, 0x31, 0x30,
|
0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61,
|
||||||
0x31, 0x36, 0x31, 0x34, 0x30, 0x31, 0x34, 0x38,
|
0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03,
|
||||||
0x5a, 0x30, 0x64, 0x31, 0x0b, 0x30, 0x09, 0x06,
|
0x55, 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74,
|
||||||
0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x4b,
|
0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69,
|
||||||
0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04,
|
0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74,
|
||||||
0x0a, 0x0c, 0x0d, 0x4f, 0x70, 0x65, 0x6e, 0x53,
|
0x79, 0x20, 0x4c, 0x74, 0x64, 0x30, 0x5c, 0x30,
|
||||||
0x53, 0x4c, 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70,
|
|
||||||
0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04,
|
|
||||||
0x0b, 0x0c, 0x19, 0x46, 0x4f, 0x52, 0x20, 0x54,
|
|
||||||
0x45, 0x53, 0x54, 0x49, 0x4e, 0x47, 0x20, 0x50,
|
|
||||||
0x55, 0x52, 0x50, 0x4f, 0x53, 0x45, 0x53, 0x20,
|
|
||||||
0x4f, 0x4e, 0x4c, 0x59, 0x31, 0x19, 0x30, 0x17,
|
|
||||||
0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x10, 0x54,
|
|
||||||
0x65, 0x73, 0x74, 0x20, 0x53, 0x65, 0x72, 0x76,
|
|
||||||
0x65, 0x72, 0x20, 0x43, 0x65, 0x72, 0x74, 0x30,
|
|
||||||
0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a,
|
|
||||||
0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
|
|
||||||
0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30,
|
|
||||||
0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00,
|
|
||||||
0xf3, 0x84, 0xf3, 0x92, 0x36, 0xdc, 0xb2, 0x46,
|
|
||||||
0xca, 0x66, 0x7a, 0xe5, 0x29, 0xc5, 0xf3, 0x49,
|
|
||||||
0x28, 0x22, 0xd3, 0xb9, 0xfe, 0xe0, 0xde, 0xe4,
|
|
||||||
0x38, 0xce, 0xee, 0x22, 0x1c, 0xe9, 0x91, 0x3b,
|
|
||||||
0x94, 0xd0, 0x72, 0x2f, 0x87, 0x85, 0x59, 0x4b,
|
|
||||||
0x66, 0xb1, 0xc5, 0xf5, 0x7a, 0x85, 0x5d, 0xc2,
|
|
||||||
0x0f, 0xd3, 0x2e, 0x29, 0x58, 0x36, 0xcc, 0x48,
|
|
||||||
0x6b, 0xa2, 0xa2, 0xb5, 0x26, 0xce, 0x67, 0xe2,
|
|
||||||
0x47, 0xb6, 0xdf, 0x49, 0xd2, 0x3f, 0xfa, 0xa2,
|
|
||||||
0x10, 0xb7, 0xc2, 0x97, 0x44, 0x7e, 0x87, 0x34,
|
|
||||||
0x6d, 0x6d, 0xf2, 0x8b, 0xb4, 0x55, 0x2b, 0xd6,
|
|
||||||
0x21, 0xde, 0x53, 0x4b, 0x90, 0xea, 0xfd, 0xea,
|
|
||||||
0xf9, 0x38, 0x35, 0x2b, 0xf4, 0xe6, 0x9a, 0x0e,
|
|
||||||
0xf6, 0xbb, 0x12, 0xab, 0x87, 0x21, 0xc3, 0x2f,
|
|
||||||
0xbc, 0xf4, 0x06, 0xb8, 0x8f, 0x8e, 0x10, 0x07,
|
|
||||||
0x27, 0x95, 0xe5, 0x42, 0xcb, 0xd1, 0xd5, 0x10,
|
|
||||||
0x8c, 0x92, 0xac, 0xee, 0x0f, 0xdc, 0x23, 0x48,
|
|
||||||
0x89, 0xc9, 0xc6, 0x93, 0x0c, 0x22, 0x02, 0xe7,
|
|
||||||
0x74, 0xe7, 0x25, 0x00, 0xab, 0xf8, 0x0f, 0x5c,
|
|
||||||
0x10, 0xb5, 0x85, 0x3b, 0x66, 0x94, 0xf0, 0xfb,
|
|
||||||
0x4d, 0x57, 0x06, 0x55, 0x21, 0x22, 0x25, 0xdb,
|
|
||||||
0xf3, 0xaa, 0xa9, 0x60, 0xbf, 0x4d, 0xaa, 0x79,
|
|
||||||
0xd1, 0xab, 0x92, 0x48, 0xba, 0x19, 0x8e, 0x12,
|
|
||||||
0xec, 0x68, 0xd9, 0xc6, 0xba, 0xdf, 0xec, 0x5a,
|
|
||||||
0x1c, 0xd8, 0x43, 0xfe, 0xe7, 0x52, 0xc9, 0xcf,
|
|
||||||
0x02, 0xd0, 0xc7, 0x7f, 0xc9, 0x7e, 0xb0, 0x94,
|
|
||||||
0xe3, 0x53, 0x44, 0x58, 0x0b, 0x2e, 0xfd, 0x29,
|
|
||||||
0x74, 0xb5, 0x06, 0x9b, 0x5c, 0x44, 0x8d, 0xfb,
|
|
||||||
0x32, 0x75, 0xa4, 0x3a, 0xa8, 0x67, 0x7b, 0x87,
|
|
||||||
0x32, 0x0a, 0x50, 0x8d, 0xe1, 0xa2, 0x13, 0x4a,
|
|
||||||
0x25, 0xaf, 0xe6, 0x1c, 0xb1, 0x25, 0xbf, 0xb4,
|
|
||||||
0x99, 0xa2, 0x53, 0xd3, 0xa2, 0x02, 0xbf, 0x11,
|
|
||||||
0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0x8f,
|
|
||||||
0x30, 0x81, 0x8c, 0x30, 0x0c, 0x06, 0x03, 0x55,
|
|
||||||
0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30,
|
|
||||||
0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f,
|
|
||||||
0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x05,
|
|
||||||
0xe0, 0x30, 0x2c, 0x06, 0x09, 0x60, 0x86, 0x48,
|
|
||||||
0x01, 0x86, 0xf8, 0x42, 0x01, 0x0d, 0x04, 0x1f,
|
|
||||||
0x16, 0x1d, 0x4f, 0x70, 0x65, 0x6e, 0x53, 0x53,
|
|
||||||
0x4c, 0x20, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61,
|
|
||||||
0x74, 0x65, 0x64, 0x20, 0x43, 0x65, 0x72, 0x74,
|
|
||||||
0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x30,
|
|
||||||
0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16,
|
|
||||||
0x04, 0x14, 0x82, 0xbc, 0xcf, 0x00, 0x00, 0x13,
|
|
||||||
0xd1, 0xf7, 0x39, 0x25, 0x9a, 0x27, 0xe7, 0xaf,
|
|
||||||
0xd2, 0xef, 0x20, 0x1b, 0x6e, 0xac, 0x30, 0x1f,
|
|
||||||
0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30,
|
|
||||||
0x16, 0x80, 0x14, 0x36, 0xc3, 0x6c, 0x88, 0xe7,
|
|
||||||
0x95, 0xfe, 0xb0, 0xbd, 0xec, 0xce, 0x3e, 0x3d,
|
|
||||||
0x86, 0xab, 0x21, 0x81, 0x87, 0xda, 0xda, 0x30,
|
|
||||||
0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
|
0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
|
||||||
0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82,
|
0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b,
|
||||||
0x01, 0x01, 0x00, 0xa9, 0xbd, 0x4d, 0x57, 0x40,
|
0x00, 0x30, 0x48, 0x02, 0x41, 0x00, 0x9f, 0xb3,
|
||||||
0x74, 0xfe, 0x96, 0xe9, 0x2b, 0xd6, 0x78, 0xfd,
|
0xc3, 0x84, 0x27, 0x95, 0xff, 0x12, 0x31, 0x52,
|
||||||
0xb3, 0x63, 0xcc, 0xf4, 0x0b, 0x4d, 0x12, 0xca,
|
0x0f, 0x15, 0xef, 0x46, 0x11, 0xc4, 0xad, 0x80,
|
||||||
0x5a, 0x74, 0x8d, 0x9b, 0xf2, 0x61, 0xe6, 0xfd,
|
0xe6, 0x36, 0x5b, 0x0f, 0xdd, 0x80, 0xd7, 0x61,
|
||||||
0x06, 0x11, 0x43, 0x84, 0xfc, 0x17, 0xa0, 0xec,
|
0x8d, 0xe0, 0xfc, 0x72, 0x45, 0x09, 0x34, 0xfe,
|
||||||
0x63, 0x63, 0x36, 0xb9, 0x9e, 0x36, 0x6a, 0xb1,
|
0x55, 0x66, 0x45, 0x43, 0x4c, 0x68, 0x97, 0x6a,
|
||||||
0x02, 0x5a, 0x6a, 0x5b, 0x3f, 0x6a, 0xa1, 0xea,
|
0xfe, 0xa8, 0xa0, 0xa5, 0xdf, 0x5f, 0x78, 0xff,
|
||||||
0x05, 0x65, 0xac, 0x7e, 0x40, 0x1a, 0x48, 0x65,
|
0xee, 0xd7, 0x64, 0xb8, 0x3f, 0x04, 0xcb, 0x6f,
|
||||||
0x88, 0xd1, 0x39, 0x4d, 0xd3, 0x4b, 0x77, 0xe9,
|
0xff, 0x2a, 0xfe, 0xfe, 0xb9, 0xed, 0x02, 0x03,
|
||||||
0xc8, 0xbb, 0x2b, 0x9e, 0x5a, 0xf4, 0x08, 0x34,
|
0x01, 0x00, 0x01, 0xa3, 0x81, 0xa7, 0x30, 0x81,
|
||||||
0x39, 0x47, 0xb9, 0x02, 0x08, 0x31, 0x9a, 0xf1,
|
0xa4, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e,
|
||||||
0xd9, 0x17, 0xc5, 0xe9, 0xa6, 0xa5, 0x96, 0x4b,
|
0x04, 0x16, 0x04, 0x14, 0x78, 0xa6, 0x97, 0x9a,
|
||||||
0x6d, 0x40, 0xa9, 0x5b, 0x65, 0x28, 0xcb, 0xcb,
|
0x63, 0xb5, 0xc5, 0xa1, 0xa5, 0x33, 0xba, 0x22,
|
||||||
0x00, 0x03, 0x82, 0x63, 0x37, 0xd3, 0xad, 0xb1,
|
0x7c, 0x23, 0x6e, 0x5b, 0x1b, 0x7a, 0xcc, 0x2b,
|
||||||
0x96, 0x3b, 0x76, 0xf5, 0x17, 0x16, 0x02, 0x7b,
|
0x30, 0x75, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04,
|
||||||
0xbd, 0x53, 0x53, 0x46, 0x72, 0x34, 0xd6, 0x08,
|
0x6e, 0x30, 0x6c, 0x80, 0x14, 0x78, 0xa6, 0x97,
|
||||||
0x64, 0x9d, 0xbb, 0x43, 0xfb, 0x64, 0xb1, 0x49,
|
0x9a, 0x63, 0xb5, 0xc5, 0xa1, 0xa5, 0x33, 0xba,
|
||||||
0x07, 0x77, 0x09, 0x61, 0x7a, 0x42, 0x17, 0x11,
|
0x22, 0x7c, 0x23, 0x6e, 0x5b, 0x1b, 0x7a, 0xcc,
|
||||||
0x30, 0x0c, 0xd9, 0x27, 0x5c, 0xf5, 0x71, 0xb6,
|
0x2b, 0xa1, 0x49, 0xa4, 0x47, 0x30, 0x45, 0x31,
|
||||||
0xf0, 0x18, 0x30, 0xf3, 0x7e, 0xf1, 0x85, 0x3f,
|
0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
|
||||||
0x32, 0x7e, 0x4a, 0xaf, 0xb3, 0x10, 0xf7, 0x6c,
|
0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11,
|
||||||
0xc6, 0x85, 0x4b, 0x2d, 0x27, 0xad, 0x0a, 0x20,
|
0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53,
|
||||||
0x5c, 0xfb, 0x8d, 0x19, 0x70, 0x34, 0xb9, 0x75,
|
0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74,
|
||||||
0x5f, 0x7c, 0x87, 0xd5, 0xc3, 0xec, 0x93, 0x13,
|
0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55,
|
||||||
0x41, 0xfc, 0x73, 0x03, 0xb9, 0x8d, 0x1a, 0xfe,
|
0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65,
|
||||||
0xf7, 0x26, 0x86, 0x49, 0x03, 0xa9, 0xc5, 0x82,
|
0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64,
|
||||||
0x3f, 0x80, 0x0d, 0x29, 0x49, 0xb1, 0x8f, 0xed,
|
0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79,
|
||||||
0x24, 0x1b, 0xfe, 0xcf, 0x58, 0x90, 0x46, 0xe7,
|
0x20, 0x4c, 0x74, 0x64, 0x82, 0x09, 0x00, 0xb1,
|
||||||
0xa8, 0x87, 0xd4, 0x1e, 0x79, 0xef, 0x99, 0x6d,
|
0x35, 0x13, 0x65, 0x11, 0x20, 0xc5, 0x92, 0x30,
|
||||||
0x18, 0x9f, 0x3e, 0x8b, 0x82, 0x07, 0xc1, 0x43,
|
0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05,
|
||||||
0xc7, 0xe0, 0x25, 0xb6, 0xf1, 0xd3, 0x00, 0xd7,
|
0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06,
|
||||||
0x40, 0xab, 0x4b, 0x7f, 0x2b, 0x7a, 0x3e, 0xa6,
|
0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
|
||||||
0x99, 0x4c, 0x54, 0x16, 0x03, 0x03, 0x01, 0x4d,
|
0x01, 0x05, 0x05, 0x00, 0x03, 0x41, 0x00, 0x85,
|
||||||
0x0c, 0x00, 0x01, 0x49, 0x03, 0x00, 0x17, 0x41,
|
0x36, 0x40, 0x73, 0xc1, 0xbb, 0x1a, 0xda, 0xd4,
|
||||||
0x04, 0x8f, 0x92, 0xa0, 0x20, 0xdc, 0x70, 0xce,
|
0x59, 0x9f, 0x2d, 0xa2, 0x70, 0x31, 0x46, 0x74,
|
||||||
0xaf, 0x50, 0x44, 0xa8, 0x53, 0x15, 0xbf, 0x74,
|
0xec, 0x83, 0x6e, 0xa8, 0xc8, 0x3c, 0x51, 0xaf,
|
||||||
0x0c, 0xed, 0x60, 0x26, 0xac, 0xb0, 0x07, 0x17,
|
0x39, 0xac, 0xec, 0x40, 0xbc, 0xe8, 0x22, 0x46,
|
||||||
0x59, 0x02, 0x6d, 0x9f, 0x45, 0x57, 0x3b, 0x9c,
|
0x1d, 0x99, 0xd6, 0x46, 0x2a, 0x24, 0xd4, 0x8b,
|
||||||
0x67, 0xae, 0xb8, 0xa6, 0x70, 0xa9, 0x03, 0xb4,
|
0x05, 0x08, 0x4b, 0xfb, 0x35, 0x11, 0x6e, 0x92,
|
||||||
0x37, 0x7b, 0xe4, 0x2f, 0x7c, 0x42, 0x4f, 0xaa,
|
0xbb, 0x77, 0xba, 0xe4, 0x12, 0xbb, 0xf4, 0xc8,
|
||||||
0x9a, 0x5d, 0x10, 0x65, 0xc1, 0xa5, 0x33, 0xff,
|
0x5e, 0x9c, 0x81, 0xa8, 0x97, 0x60, 0x4c, 0x16,
|
||||||
0xc5, 0xdf, 0x24, 0xdb, 0x8f, 0xe2, 0x14, 0xee,
|
0x03, 0x03, 0x00, 0x8d, 0x0c, 0x00, 0x00, 0x89,
|
||||||
0x00, 0x04, 0x01, 0x01, 0x00, 0x76, 0xcf, 0xe6,
|
0x03, 0x00, 0x17, 0x41, 0x04, 0x39, 0xe9, 0x59,
|
||||||
0x47, 0xcf, 0xc1, 0x58, 0xf5, 0x5d, 0x3a, 0x0b,
|
0x24, 0x76, 0xf0, 0x1a, 0xd6, 0x21, 0xa5, 0xbc,
|
||||||
0xd5, 0x4e, 0xb1, 0x08, 0xa6, 0x03, 0x8b, 0xa3,
|
0x28, 0xb9, 0xd5, 0x3d, 0xf7, 0xf3, 0xbe, 0x09,
|
||||||
0x7b, 0x9c, 0xa2, 0x3b, 0x99, 0x7e, 0x42, 0x0d,
|
0xff, 0xc1, 0x79, 0x33, 0x82, 0xf8, 0xe1, 0x5f,
|
||||||
0x38, 0x6e, 0x9a, 0x5e, 0xf7, 0x45, 0x7f, 0xf3,
|
0x1c, 0x34, 0x96, 0x3a, 0x10, 0xf2, 0x2c, 0x69,
|
||||||
0x51, 0xa2, 0xe6, 0xae, 0x1c, 0x55, 0x2a, 0x58,
|
0xab, 0x57, 0xf6, 0x20, 0xb6, 0x59, 0x1f, 0x8c,
|
||||||
0x13, 0x55, 0xa9, 0x93, 0xac, 0x6a, 0x1e, 0xd6,
|
0x3e, 0xa2, 0xac, 0x4d, 0xf2, 0x10, 0x58, 0x0b,
|
||||||
0xd9, 0x98, 0x89, 0x93, 0x16, 0x8f, 0xab, 0xc5,
|
0x61, 0x27, 0x6c, 0x47, 0xa0, 0x52, 0xc7, 0xe6,
|
||||||
0x65, 0x65, 0x62, 0x68, 0xd8, 0xbf, 0xbd, 0x4e,
|
0x36, 0xfd, 0xb1, 0xa2, 0x49, 0x04, 0x01, 0x00,
|
||||||
0x1a, 0x17, 0x24, 0x9c, 0x3c, 0x56, 0xf5, 0x8f,
|
0x40, 0x99, 0x7e, 0xf9, 0xed, 0x8b, 0x62, 0x82,
|
||||||
0xda, 0x6e, 0x03, 0xe7, 0xe9, 0xce, 0xe5, 0xb1,
|
0x00, 0xde, 0x5f, 0x2f, 0xb9, 0xf9, 0x9d, 0xa1,
|
||||||
0x68, 0xd8, 0x88, 0xdb, 0xde, 0xfe, 0x98, 0xbe,
|
0xb0, 0x14, 0x05, 0xc1, 0xdd, 0xa3, 0xb9, 0x08,
|
||||||
0x9d, 0x1f, 0x86, 0xbf, 0x36, 0xe5, 0xe9, 0x77,
|
0xa5, 0x36, 0xb6, 0xfe, 0x8a, 0x5b, 0x2d, 0x6e,
|
||||||
0xc3, 0xa6, 0xa3, 0x30, 0x60, 0x9f, 0x36, 0x65,
|
0xd8, 0x5a, 0x5c, 0x89, 0x84, 0x85, 0x56, 0x01,
|
||||||
0x4c, 0xe5, 0xb6, 0x3f, 0xf8, 0x15, 0x76, 0xac,
|
0xaf, 0x43, 0xd3, 0x0f, 0x85, 0xd0, 0xb2, 0x35,
|
||||||
0x4f, 0xb5, 0x8a, 0x98, 0xe3, 0xc2, 0xbd, 0x13,
|
0x3d, 0x1d, 0xd6, 0x67, 0x52, 0x48, 0xe8, 0x82,
|
||||||
0xff, 0x59, 0xfd, 0x22, 0xbf, 0xb3, 0x02, 0xab,
|
0x47, 0xbb, 0x2a, 0x54, 0x4a, 0x55, 0xcd, 0x10,
|
||||||
0xf1, 0x82, 0xff, 0x4c, 0x41, 0x81, 0x15, 0xa5,
|
0x54, 0x16, 0x03, 0x03, 0x00, 0x04, 0x0e, 0x00,
|
||||||
0xc7, 0x56, 0x93, 0xc3, 0xb0, 0xd2, 0x70, 0x84,
|
0x00, 0x00,
|
||||||
0xb6, 0x27, 0x43, 0x47, 0x38, 0x3a, 0xcf, 0x20,
|
|
||||||
0xa4, 0x97, 0x61, 0xc7, 0xf9, 0xb2, 0x01, 0xea,
|
|
||||||
0x83, 0x72, 0x00, 0x74, 0x3e, 0x41, 0xd0, 0x24,
|
|
||||||
0x32, 0xf7, 0xe1, 0x68, 0xae, 0x06, 0xcb, 0x70,
|
|
||||||
0x06, 0x3a, 0x3a, 0xd3, 0x97, 0x7e, 0xaa, 0x27,
|
|
||||||
0xb7, 0xcc, 0xd3, 0x7f, 0xb2, 0x07, 0x9e, 0x85,
|
|
||||||
0x16, 0x25, 0x28, 0xee, 0xc7, 0x29, 0x09, 0x56,
|
|
||||||
0x94, 0x6c, 0x7e, 0xe4, 0x61, 0x7b, 0xc2, 0xd5,
|
|
||||||
0x03, 0x46, 0x71, 0x69, 0xc0, 0x90, 0x0e, 0x58,
|
|
||||||
0xc6, 0xef, 0xf5, 0x23, 0x03, 0x42, 0x92, 0x1a,
|
|
||||||
0x2f, 0x4b, 0x0a, 0x5d, 0x74, 0x71, 0x28, 0x5a,
|
|
||||||
0x83, 0xf2, 0x00, 0x79, 0x65, 0x89, 0x61, 0x87,
|
|
||||||
0x31, 0xf0, 0x09, 0x89, 0x6a, 0xc4, 0x48, 0xee,
|
|
||||||
0x78, 0xf1, 0x65, 0x3f, 0xe1, 0x16, 0x03, 0x03,
|
|
||||||
0x00, 0x5a, 0x0d, 0x00, 0x00, 0x52, 0x03, 0x01,
|
|
||||||
0x02, 0x40, 0x00, 0x20, 0x06, 0x01, 0x06, 0x02,
|
|
||||||
0x06, 0x03, 0x05, 0x01, 0x05, 0x02, 0x05, 0x03,
|
|
||||||
0x04, 0x01, 0x04, 0x02, 0x04, 0x03, 0x03, 0x01,
|
|
||||||
0x03, 0x02, 0x03, 0x03, 0x02, 0x01, 0x02, 0x02,
|
|
||||||
0x02, 0x03, 0x01, 0x01, 0x00, 0x2a, 0x00, 0x28,
|
|
||||||
0x30, 0x26, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03,
|
|
||||||
0x55, 0x04, 0x0a, 0x13, 0x07, 0x41, 0x63, 0x6d,
|
|
||||||
0x65, 0x20, 0x43, 0x6f, 0x31, 0x12, 0x30, 0x10,
|
|
||||||
0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x09, 0x31,
|
|
||||||
0x32, 0x37, 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x31,
|
|
||||||
0x0e, 0x00, 0x00, 0x00,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
0x16, 0x03, 0x03, 0x00, 0x07, 0x0b, 0x00, 0x00,
|
0x16, 0x03, 0x03, 0x00, 0x46, 0x10, 0x00, 0x00,
|
||||||
0x03, 0x00, 0x00, 0x00, 0x16, 0x03, 0x03, 0x00,
|
0x42, 0x41, 0x04, 0x1e, 0x18, 0x37, 0xef, 0x0d,
|
||||||
0x46, 0x10, 0x00, 0x00, 0x42, 0x41, 0x04, 0x1e,
|
0x19, 0x51, 0x88, 0x35, 0x75, 0x71, 0xb5, 0xe5,
|
||||||
0x18, 0x37, 0xef, 0x0d, 0x19, 0x51, 0x88, 0x35,
|
0x54, 0x5b, 0x12, 0x2e, 0x8f, 0x09, 0x67, 0xfd,
|
||||||
0x75, 0x71, 0xb5, 0xe5, 0x54, 0x5b, 0x12, 0x2e,
|
0xa7, 0x24, 0x20, 0x3e, 0xb2, 0x56, 0x1c, 0xce,
|
||||||
0x8f, 0x09, 0x67, 0xfd, 0xa7, 0x24, 0x20, 0x3e,
|
0x97, 0x28, 0x5e, 0xf8, 0x2b, 0x2d, 0x4f, 0x9e,
|
||||||
0xb2, 0x56, 0x1c, 0xce, 0x97, 0x28, 0x5e, 0xf8,
|
0xf1, 0x07, 0x9f, 0x6c, 0x4b, 0x5b, 0x83, 0x56,
|
||||||
0x2b, 0x2d, 0x4f, 0x9e, 0xf1, 0x07, 0x9f, 0x6c,
|
0xe2, 0x32, 0x42, 0xe9, 0x58, 0xb6, 0xd7, 0x49,
|
||||||
0x4b, 0x5b, 0x83, 0x56, 0xe2, 0x32, 0x42, 0xe9,
|
0xa6, 0xb5, 0x68, 0x1a, 0x41, 0x03, 0x56, 0x6b,
|
||||||
0x58, 0xb6, 0xd7, 0x49, 0xa6, 0xb5, 0x68, 0x1a,
|
0xdc, 0x5a, 0x89, 0x14, 0x03, 0x03, 0x00, 0x01,
|
||||||
0x41, 0x03, 0x56, 0x6b, 0xdc, 0x5a, 0x89, 0x14,
|
0x01, 0x16, 0x03, 0x03, 0x00, 0x40, 0x00, 0x00,
|
||||||
0x03, 0x03, 0x00, 0x01, 0x01, 0x16, 0x03, 0x03,
|
|
||||||
0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x1f, 0xb8, 0x47, 0xfb, 0xd2, 0xba,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0xcb,
|
||||||
0x62, 0x74, 0x63, 0x54, 0xb8, 0x03, 0x7b, 0xb9,
|
0x97, 0x41, 0x63, 0x39, 0xeb, 0xda, 0x04, 0x39,
|
||||||
0x05, 0x87, 0x60, 0x6f, 0xb9, 0xfc, 0x79, 0x96,
|
0xfb, 0x67, 0x1d, 0x6d, 0xf8, 0x58, 0xd1, 0x22,
|
||||||
0xce, 0xf0, 0x84, 0x77, 0x23, 0x1b, 0x44, 0x3f,
|
0x35, 0xe3, 0xc3, 0x9d, 0xfc, 0x4e, 0xcc, 0x71,
|
||||||
0x33, 0xe8, 0x71, 0x97, 0x9d, 0xd3, 0x7d, 0x43,
|
0x93, 0x78, 0x64, 0x39, 0x04, 0xa0, 0xa9, 0x41,
|
||||||
0x40, 0xd3, 0x95, 0x65, 0x1f, 0x2c, 0x30, 0xfd,
|
0xcf, 0x4c, 0xd6, 0x34, 0xad, 0x5c, 0xc9, 0x7a,
|
||||||
0x7f, 0xac,
|
0x44, 0xb1, 0x1d, 0x77, 0x52, 0x01,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
0x14, 0x03, 0x03, 0x00, 0x01, 0x01, 0x16, 0x03,
|
0x14, 0x03, 0x03, 0x00, 0x01, 0x01, 0x16, 0x03,
|
||||||
0x03, 0x00, 0x40, 0x64, 0x09, 0x6c, 0x06, 0x5a,
|
0x03, 0x00, 0x40, 0x55, 0x75, 0x8a, 0x57, 0xb4,
|
||||||
0x01, 0x24, 0x10, 0xd9, 0x92, 0x66, 0xe6, 0x28,
|
0x53, 0xa2, 0x8f, 0xbf, 0xd3, 0x79, 0x72, 0x1e,
|
||||||
0x43, 0x2f, 0xba, 0x0b, 0x17, 0x61, 0x55, 0x42,
|
0x94, 0x53, 0xb3, 0x03, 0x9d, 0x4d, 0x8a, 0x1f,
|
||||||
0x9d, 0xc3, 0x59, 0xba, 0x57, 0x19, 0x1b, 0x74,
|
0xbd, 0x25, 0x79, 0x69, 0x61, 0x65, 0xd7, 0x26,
|
||||||
0x22, 0x40, 0xc7, 0x13, 0x95, 0x83, 0xe6, 0xf3,
|
0xad, 0xa6, 0x0e, 0x89, 0x83, 0xc0, 0xbe, 0x46,
|
||||||
0x11, 0x62, 0xe6, 0xde, 0xfc, 0xf3, 0x1a, 0xd1,
|
0x51, 0xe4, 0x38, 0x7b, 0x65, 0x74, 0x6d, 0x24,
|
||||||
0x3d, 0xce, 0xd1, 0xf9, 0xeb, 0x2e, 0x13, 0x39,
|
0xff, 0xd4, 0x9f, 0xcb, 0xfc, 0xd7, 0x03, 0xaa,
|
||||||
0xa6, 0xdb, 0x04, 0x79, 0xaa, 0x2d, 0xe1, 0xa4,
|
0x7b, 0x8e, 0x30, 0x09, 0xdb, 0xaa, 0x9d, 0xad,
|
||||||
0xd0, 0xf9, 0x36,
|
0xcd, 0x56, 0xcf,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
0x17, 0x03, 0x03, 0x00, 0x30, 0x00, 0x00, 0x00,
|
0x17, 0x03, 0x03, 0x00, 0x30, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x88, 0x3d,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0xab, 0x01, 0x46,
|
||||||
0xcb, 0x65, 0xc1, 0xac, 0x94, 0xc5, 0x1d, 0x4d,
|
0xa8, 0xdd, 0x62, 0x73, 0x67, 0x99, 0x01, 0x42,
|
||||||
0xc5, 0x1e, 0xd4, 0x17, 0xe3, 0x83, 0xac, 0x14,
|
0xb2, 0x9e, 0x22, 0x18, 0xf5, 0x8f, 0x10, 0x97,
|
||||||
0x80, 0x92, 0x2d, 0x5b, 0x42, 0x19, 0xcb, 0x51,
|
0xde, 0x58, 0x24, 0x34, 0x36, 0xa2, 0x5d, 0xf4,
|
||||||
0xc9, 0x48, 0xdf, 0xf6, 0x27, 0x15, 0x03, 0x03,
|
0x96, 0x2a, 0xed, 0x6c, 0x06, 0x15, 0x03, 0x03,
|
||||||
0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0xf7, 0xc2, 0xed, 0x1a, 0x88, 0xb6,
|
0x00, 0x00, 0x9f, 0x7a, 0x9f, 0xab, 0xf5, 0x4e,
|
||||||
0xb8, 0x26, 0x04, 0x31, 0x89, 0xab, 0x29, 0x34,
|
0x1c, 0x4e, 0xf4, 0xcb, 0x1a, 0x39, 0xae, 0x21,
|
||||||
0xce, 0x84, 0x81, 0x33, 0x64, 0x8e, 0x53, 0xa3,
|
0x85, 0x39, 0xc4, 0x51, 0xac, 0x14, 0xde, 0xa0,
|
||||||
0xaf, 0x8b, 0x5a, 0x50, 0x43, 0xab, 0x77, 0x77,
|
0xe7, 0x70, 0x7c, 0x6a, 0x53, 0x54, 0x19, 0xbc,
|
||||||
0xa3, 0xc7,
|
0x2f, 0x32,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2358,3 +2279,208 @@ var testClientChainCertificate = fromHex(
|
|||||||
"77796d5a695731673d3d0a2d2d2d2d2d454e4420" +
|
"77796d5a695731673d3d0a2d2d2d2d2d454e4420" +
|
||||||
"43455254494649434154452d2d2d2d2d0a",
|
"43455254494649434154452d2d2d2d2d0a",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Script of interaction with openssl implementation:
|
||||||
|
//
|
||||||
|
// openssl s_server -cipher ECDHE-ECDSA-AES128-SHA \
|
||||||
|
// -key server.key -cert server.crt -port 10443
|
||||||
|
//
|
||||||
|
// The values for this test are obtained by building and running in client mode:
|
||||||
|
// % go test -test.run "TestRunClient" -connect -ciphersuites=0xc009
|
||||||
|
// The recorded bytes are written to stdout.
|
||||||
|
//
|
||||||
|
// The server private key is:
|
||||||
|
//
|
||||||
|
// -----BEGIN EC PARAMETERS-----
|
||||||
|
// BgUrgQQAIw==
|
||||||
|
// -----END EC PARAMETERS-----
|
||||||
|
// -----BEGIN EC PRIVATE KEY-----
|
||||||
|
// MIHcAgEBBEIBmIPpCa0Kyeo9M/nq5mHxeFIGlw+MqakWcvHu3Keo7xK9ZWG7JG3a
|
||||||
|
// XfS01efjqSZJvF2DoL+Sly4A5iBn0Me9mdegBwYFK4EEACOhgYkDgYYABADEoe2+
|
||||||
|
// mPkLSHM2fsMWVhEi8j1TwztNIT3Na3Xm9rDcmt8mwbyyh/ByMnyzZC8ckLzqaCMQ
|
||||||
|
// fv7jJcBIOmngKG3TNwDvBGLdDaCccGKD2IHTZDGqnpcxvZawaMCbI952ZD8aXH/p
|
||||||
|
// Eg5YWLZfcN2b2OrV1/XVzLm2nzBmW2aaIOIn5b/+Ow==
|
||||||
|
// -----END EC PRIVATE KEY-----
|
||||||
|
//
|
||||||
|
// and certificate is:
|
||||||
|
//
|
||||||
|
// -----BEGIN CERTIFICATE-----
|
||||||
|
// MIICADCCAWICCQC4vy1HoNLr9DAJBgcqhkjOPQQBMEUxCzAJBgNVBAYTAkFVMRMw
|
||||||
|
// EQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0
|
||||||
|
// eSBMdGQwHhcNMTIxMTIyMTUwNjMyWhcNMjIxMTIwMTUwNjMyWjBFMQswCQYDVQQG
|
||||||
|
// EwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lk
|
||||||
|
// Z2l0cyBQdHkgTHRkMIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQAxKHtvpj5C0hz
|
||||||
|
// Nn7DFlYRIvI9U8M7TSE9zWt15vaw3JrfJsG8sofwcjJ8s2QvHJC86mgjEH7+4yXA
|
||||||
|
// SDpp4Cht0zcA7wRi3Q2gnHBig9iB02Qxqp6XMb2WsGjAmyPedmQ/Glx/6RIOWFi2
|
||||||
|
// X3Ddm9jq1df11cy5tp8wZltmmiDiJ+W//jswCQYHKoZIzj0EAQOBjAAwgYgCQgGI
|
||||||
|
// ok/r4kXFSH0brPXtmJ2uR3DAXhu2L73xtk23YUDTEaLO7gt+kn7/dp3DO36lP876
|
||||||
|
// EOJZ7EctfKzaTpcOFaBv0AJCAU38vmcTnC0FDr0/o4wlwTMTgw2UBrvUN3r27HrJ
|
||||||
|
// hi7d1xFpf4V8Vt77MXgr5Md4Da7Lvp5ONiQxe2oPOZUSB48q
|
||||||
|
// -----END CERTIFICATE-----
|
||||||
|
var ecdheECDSAAESClientScript = [][]byte{
|
||||||
|
{
|
||||||
|
0x16, 0x03, 0x01, 0x00, 0x4a, 0x01, 0x00, 0x00,
|
||||||
|
0x46, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xc0, 0x09,
|
||||||
|
0x01, 0x00, 0x00, 0x1b, 0x00, 0x05, 0x00, 0x05,
|
||||||
|
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00,
|
||||||
|
0x08, 0x00, 0x06, 0x00, 0x17, 0x00, 0x18, 0x00,
|
||||||
|
0x19, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
0x16, 0x03, 0x01, 0x00, 0x54, 0x02, 0x00, 0x00,
|
||||||
|
0x50, 0x03, 0x01, 0x50, 0xd7, 0x19, 0xc9, 0x03,
|
||||||
|
0xc2, 0x3a, 0xc6, 0x1f, 0x0a, 0x84, 0x9e, 0xd7,
|
||||||
|
0xf4, 0x7e, 0x07, 0x6d, 0xa8, 0xe4, 0xa9, 0x4f,
|
||||||
|
0x22, 0x50, 0xa2, 0x19, 0x24, 0x44, 0x42, 0x65,
|
||||||
|
0xaa, 0xba, 0x3a, 0x20, 0x90, 0x70, 0xb7, 0xe5,
|
||||||
|
0x57, 0xed, 0xb1, 0xb1, 0x43, 0x4b, 0xa1, 0x4e,
|
||||||
|
0xee, 0x7a, 0x5b, 0x88, 0xf6, 0xa6, 0x73, 0x3b,
|
||||||
|
0xcb, 0xa7, 0xbd, 0x57, 0x50, 0xf2, 0x72, 0x8c,
|
||||||
|
0xbc, 0x45, 0x73, 0xaa, 0xc0, 0x09, 0x00, 0x00,
|
||||||
|
0x08, 0x00, 0x0b, 0x00, 0x04, 0x03, 0x00, 0x01,
|
||||||
|
0x02, 0x16, 0x03, 0x01, 0x02, 0x0e, 0x0b, 0x00,
|
||||||
|
0x02, 0x0a, 0x00, 0x02, 0x07, 0x00, 0x02, 0x04,
|
||||||
|
0x30, 0x82, 0x02, 0x00, 0x30, 0x82, 0x01, 0x62,
|
||||||
|
0x02, 0x09, 0x00, 0xb8, 0xbf, 0x2d, 0x47, 0xa0,
|
||||||
|
0xd2, 0xeb, 0xf4, 0x30, 0x09, 0x06, 0x07, 0x2a,
|
||||||
|
0x86, 0x48, 0xce, 0x3d, 0x04, 0x01, 0x30, 0x45,
|
||||||
|
0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
|
||||||
|
0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30,
|
||||||
|
0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a,
|
||||||
|
0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61,
|
||||||
|
0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03,
|
||||||
|
0x55, 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74,
|
||||||
|
0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69,
|
||||||
|
0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74,
|
||||||
|
0x79, 0x20, 0x4c, 0x74, 0x64, 0x30, 0x1e, 0x17,
|
||||||
|
0x0d, 0x31, 0x32, 0x31, 0x31, 0x32, 0x32, 0x31,
|
||||||
|
0x35, 0x30, 0x36, 0x33, 0x32, 0x5a, 0x17, 0x0d,
|
||||||
|
0x32, 0x32, 0x31, 0x31, 0x32, 0x30, 0x31, 0x35,
|
||||||
|
0x30, 0x36, 0x33, 0x32, 0x5a, 0x30, 0x45, 0x31,
|
||||||
|
0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
|
||||||
|
0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11,
|
||||||
|
0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53,
|
||||||
|
0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74,
|
||||||
|
0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55,
|
||||||
|
0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65,
|
||||||
|
0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64,
|
||||||
|
0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79,
|
||||||
|
0x20, 0x4c, 0x74, 0x64, 0x30, 0x81, 0x9b, 0x30,
|
||||||
|
0x10, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d,
|
||||||
|
0x02, 0x01, 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00,
|
||||||
|
0x23, 0x03, 0x81, 0x86, 0x00, 0x04, 0x00, 0xc4,
|
||||||
|
0xa1, 0xed, 0xbe, 0x98, 0xf9, 0x0b, 0x48, 0x73,
|
||||||
|
0x36, 0x7e, 0xc3, 0x16, 0x56, 0x11, 0x22, 0xf2,
|
||||||
|
0x3d, 0x53, 0xc3, 0x3b, 0x4d, 0x21, 0x3d, 0xcd,
|
||||||
|
0x6b, 0x75, 0xe6, 0xf6, 0xb0, 0xdc, 0x9a, 0xdf,
|
||||||
|
0x26, 0xc1, 0xbc, 0xb2, 0x87, 0xf0, 0x72, 0x32,
|
||||||
|
0x7c, 0xb3, 0x64, 0x2f, 0x1c, 0x90, 0xbc, 0xea,
|
||||||
|
0x68, 0x23, 0x10, 0x7e, 0xfe, 0xe3, 0x25, 0xc0,
|
||||||
|
0x48, 0x3a, 0x69, 0xe0, 0x28, 0x6d, 0xd3, 0x37,
|
||||||
|
0x00, 0xef, 0x04, 0x62, 0xdd, 0x0d, 0xa0, 0x9c,
|
||||||
|
0x70, 0x62, 0x83, 0xd8, 0x81, 0xd3, 0x64, 0x31,
|
||||||
|
0xaa, 0x9e, 0x97, 0x31, 0xbd, 0x96, 0xb0, 0x68,
|
||||||
|
0xc0, 0x9b, 0x23, 0xde, 0x76, 0x64, 0x3f, 0x1a,
|
||||||
|
0x5c, 0x7f, 0xe9, 0x12, 0x0e, 0x58, 0x58, 0xb6,
|
||||||
|
0x5f, 0x70, 0xdd, 0x9b, 0xd8, 0xea, 0xd5, 0xd7,
|
||||||
|
0xf5, 0xd5, 0xcc, 0xb9, 0xb6, 0x9f, 0x30, 0x66,
|
||||||
|
0x5b, 0x66, 0x9a, 0x20, 0xe2, 0x27, 0xe5, 0xbf,
|
||||||
|
0xfe, 0x3b, 0x30, 0x09, 0x06, 0x07, 0x2a, 0x86,
|
||||||
|
0x48, 0xce, 0x3d, 0x04, 0x01, 0x03, 0x81, 0x8c,
|
||||||
|
0x00, 0x30, 0x81, 0x88, 0x02, 0x42, 0x01, 0x88,
|
||||||
|
0xa2, 0x4f, 0xeb, 0xe2, 0x45, 0xc5, 0x48, 0x7d,
|
||||||
|
0x1b, 0xac, 0xf5, 0xed, 0x98, 0x9d, 0xae, 0x47,
|
||||||
|
0x70, 0xc0, 0x5e, 0x1b, 0xb6, 0x2f, 0xbd, 0xf1,
|
||||||
|
0xb6, 0x4d, 0xb7, 0x61, 0x40, 0xd3, 0x11, 0xa2,
|
||||||
|
0xce, 0xee, 0x0b, 0x7e, 0x92, 0x7e, 0xff, 0x76,
|
||||||
|
0x9d, 0xc3, 0x3b, 0x7e, 0xa5, 0x3f, 0xce, 0xfa,
|
||||||
|
0x10, 0xe2, 0x59, 0xec, 0x47, 0x2d, 0x7c, 0xac,
|
||||||
|
0xda, 0x4e, 0x97, 0x0e, 0x15, 0xa0, 0x6f, 0xd0,
|
||||||
|
0x02, 0x42, 0x01, 0x4d, 0xfc, 0xbe, 0x67, 0x13,
|
||||||
|
0x9c, 0x2d, 0x05, 0x0e, 0xbd, 0x3f, 0xa3, 0x8c,
|
||||||
|
0x25, 0xc1, 0x33, 0x13, 0x83, 0x0d, 0x94, 0x06,
|
||||||
|
0xbb, 0xd4, 0x37, 0x7a, 0xf6, 0xec, 0x7a, 0xc9,
|
||||||
|
0x86, 0x2e, 0xdd, 0xd7, 0x11, 0x69, 0x7f, 0x85,
|
||||||
|
0x7c, 0x56, 0xde, 0xfb, 0x31, 0x78, 0x2b, 0xe4,
|
||||||
|
0xc7, 0x78, 0x0d, 0xae, 0xcb, 0xbe, 0x9e, 0x4e,
|
||||||
|
0x36, 0x24, 0x31, 0x7b, 0x6a, 0x0f, 0x39, 0x95,
|
||||||
|
0x12, 0x07, 0x8f, 0x2a, 0x16, 0x03, 0x01, 0x00,
|
||||||
|
0xd6, 0x0c, 0x00, 0x00, 0xd2, 0x03, 0x00, 0x17,
|
||||||
|
0x41, 0x04, 0x33, 0xed, 0xe1, 0x10, 0x3d, 0xe2,
|
||||||
|
0xb0, 0x81, 0x5e, 0x01, 0x1b, 0x00, 0x4a, 0x7d,
|
||||||
|
0xdc, 0xc5, 0x78, 0x02, 0xb1, 0x9a, 0x78, 0x92,
|
||||||
|
0x34, 0xd9, 0x23, 0xcc, 0x01, 0xfb, 0x0c, 0x49,
|
||||||
|
0x1c, 0x4a, 0x59, 0x8a, 0x80, 0x1b, 0x34, 0xf0,
|
||||||
|
0xe8, 0x87, 0x1b, 0x7c, 0xfb, 0x72, 0xf5, 0xea,
|
||||||
|
0xf9, 0xf3, 0xff, 0xa6, 0x3e, 0x4e, 0xac, 0xbc,
|
||||||
|
0xee, 0x14, 0x2b, 0x87, 0xd4, 0x0b, 0xda, 0x19,
|
||||||
|
0x60, 0x2b, 0x00, 0x8b, 0x30, 0x81, 0x88, 0x02,
|
||||||
|
0x42, 0x01, 0x75, 0x46, 0x4f, 0x97, 0x9f, 0xc5,
|
||||||
|
0xf9, 0x4c, 0x38, 0xcf, 0x3b, 0x37, 0x1a, 0x6b,
|
||||||
|
0x53, 0xfc, 0x05, 0x73, 0x7d, 0x98, 0x2c, 0x5b,
|
||||||
|
0x76, 0xd4, 0x37, 0x1f, 0x50, 0x6d, 0xad, 0xc6,
|
||||||
|
0x0f, 0x8f, 0x7b, 0xcc, 0x60, 0x8e, 0x04, 0x00,
|
||||||
|
0x21, 0x80, 0xa8, 0xa5, 0x98, 0xf2, 0x42, 0xf2,
|
||||||
|
0xc3, 0xf6, 0x44, 0x50, 0xc4, 0x7a, 0xae, 0x6f,
|
||||||
|
0x74, 0xa0, 0x7f, 0x07, 0x7a, 0x0b, 0xbb, 0x41,
|
||||||
|
0x9e, 0x3c, 0x0b, 0x02, 0x42, 0x01, 0xbe, 0x64,
|
||||||
|
0xaa, 0x12, 0x03, 0xfb, 0xd8, 0x4f, 0x93, 0xf9,
|
||||||
|
0x92, 0x54, 0x0d, 0x9c, 0x9d, 0x53, 0x88, 0x19,
|
||||||
|
0x69, 0x94, 0xfc, 0xd6, 0xf7, 0x60, 0xcf, 0x70,
|
||||||
|
0x64, 0x15, 0x1b, 0x02, 0x22, 0x56, 0xb0, 0x2c,
|
||||||
|
0xb1, 0x72, 0x4c, 0x9e, 0x7b, 0xf0, 0x53, 0x97,
|
||||||
|
0x43, 0xac, 0x11, 0x62, 0xe5, 0x5a, 0xf1, 0x7e,
|
||||||
|
0x87, 0x8f, 0x5c, 0x43, 0x1d, 0xae, 0x56, 0x28,
|
||||||
|
0xdb, 0x76, 0x15, 0xd8, 0x1c, 0x73, 0xce, 0x16,
|
||||||
|
0x03, 0x01, 0x00, 0x04, 0x0e, 0x00, 0x00, 0x00,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
0x16, 0x03, 0x01, 0x00, 0x46, 0x10, 0x00, 0x00,
|
||||||
|
0x42, 0x41, 0x04, 0x1e, 0x18, 0x37, 0xef, 0x0d,
|
||||||
|
0x19, 0x51, 0x88, 0x35, 0x75, 0x71, 0xb5, 0xe5,
|
||||||
|
0x54, 0x5b, 0x12, 0x2e, 0x8f, 0x09, 0x67, 0xfd,
|
||||||
|
0xa7, 0x24, 0x20, 0x3e, 0xb2, 0x56, 0x1c, 0xce,
|
||||||
|
0x97, 0x28, 0x5e, 0xf8, 0x2b, 0x2d, 0x4f, 0x9e,
|
||||||
|
0xf1, 0x07, 0x9f, 0x6c, 0x4b, 0x5b, 0x83, 0x56,
|
||||||
|
0xe2, 0x32, 0x42, 0xe9, 0x58, 0xb6, 0xd7, 0x49,
|
||||||
|
0xa6, 0xb5, 0x68, 0x1a, 0x41, 0x03, 0x56, 0x6b,
|
||||||
|
0xdc, 0x5a, 0x89, 0x14, 0x03, 0x01, 0x00, 0x01,
|
||||||
|
0x01, 0x16, 0x03, 0x01, 0x00, 0x30, 0x1a, 0x45,
|
||||||
|
0x92, 0x3b, 0xac, 0x8d, 0x91, 0x89, 0xd3, 0x2c,
|
||||||
|
0xf4, 0x3c, 0x5f, 0x70, 0xf1, 0x79, 0xa5, 0x6a,
|
||||||
|
0xcf, 0x97, 0x8f, 0x3f, 0x73, 0x08, 0xca, 0x3f,
|
||||||
|
0x55, 0xb0, 0x28, 0xd1, 0x6f, 0xcd, 0x9b, 0xca,
|
||||||
|
0xb6, 0xb7, 0xd0, 0xa5, 0x21, 0x5b, 0x08, 0xf8,
|
||||||
|
0x42, 0xe2, 0xdf, 0x25, 0x6a, 0x16,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
0x14, 0x03, 0x01, 0x00, 0x01, 0x01, 0x16, 0x03,
|
||||||
|
0x01, 0x00, 0x30, 0x30, 0x83, 0xb6, 0x51, 0x8a,
|
||||||
|
0x85, 0x4a, 0xee, 0xe4, 0xb6, 0xae, 0xf3, 0xc1,
|
||||||
|
0xdc, 0xd2, 0x04, 0xb3, 0xd0, 0x25, 0x47, 0x5f,
|
||||||
|
0xac, 0x83, 0xa3, 0x7d, 0xcf, 0x47, 0x92, 0xed,
|
||||||
|
0x92, 0x6c, 0xd1, 0x6e, 0xfd, 0x63, 0xf5, 0x2d,
|
||||||
|
0x89, 0xd8, 0x04, 0x8c, 0x62, 0x71, 0xae, 0x5e,
|
||||||
|
0x32, 0x48, 0xf8,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
0x17, 0x03, 0x01, 0x00, 0x20, 0xcf, 0x5e, 0xba,
|
||||||
|
0xf4, 0x47, 0x32, 0x35, 0x9b, 0x85, 0xdc, 0xb3,
|
||||||
|
0xff, 0x77, 0x90, 0xd9, 0x2b, 0xbd, 0x59, 0x2a,
|
||||||
|
0x33, 0xe4, 0x6e, 0x9b, 0xfc, 0x1c, 0x73, 0x3f,
|
||||||
|
0x5e, 0x1e, 0xe3, 0xa4, 0xc2, 0x17, 0x03, 0x01,
|
||||||
|
0x00, 0x20, 0x05, 0xdf, 0x2d, 0x9b, 0x29, 0x7f,
|
||||||
|
0x97, 0xcd, 0x49, 0x04, 0x53, 0x22, 0x1a, 0xa1,
|
||||||
|
0xa1, 0xe6, 0x38, 0x3a, 0x56, 0x37, 0x1f, 0xd8,
|
||||||
|
0x3a, 0x12, 0x2c, 0xf0, 0xeb, 0x61, 0x35, 0x76,
|
||||||
|
0xe5, 0xf0, 0x15, 0x03, 0x01, 0x00, 0x20, 0xa5,
|
||||||
|
0x56, 0xb5, 0x49, 0x4b, 0xc2, 0xd4, 0x4c, 0xf6,
|
||||||
|
0x95, 0x15, 0x7d, 0x41, 0x1d, 0x5c, 0x00, 0x0e,
|
||||||
|
0x20, 0xb1, 0x0a, 0xbc, 0xc9, 0x2a, 0x09, 0x17,
|
||||||
|
0xb4, 0xaa, 0x1c, 0x79, 0xda, 0x79, 0x27,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
@ -5,9 +5,12 @@
|
|||||||
package tls
|
package tls
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto"
|
||||||
|
"crypto/ecdsa"
|
||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
"crypto/subtle"
|
"crypto/subtle"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
|
"encoding/asn1"
|
||||||
"errors"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
)
|
)
|
||||||
@ -305,7 +308,10 @@ func (hs *serverHandshakeState) doFullHandshake() error {
|
|||||||
if config.ClientAuth >= RequestClientCert {
|
if config.ClientAuth >= RequestClientCert {
|
||||||
// Request a client certificate
|
// Request a client certificate
|
||||||
certReq := new(certificateRequestMsg)
|
certReq := new(certificateRequestMsg)
|
||||||
certReq.certificateTypes = []byte{certTypeRSASign}
|
certReq.certificateTypes = []byte{
|
||||||
|
byte(certTypeRSASign),
|
||||||
|
byte(certTypeECDSASign),
|
||||||
|
}
|
||||||
if c.vers >= VersionTLS12 {
|
if c.vers >= VersionTLS12 {
|
||||||
certReq.hasSignatureAndHash = true
|
certReq.hasSignatureAndHash = true
|
||||||
certReq.signatureAndHashes = supportedSignatureAlgorithms
|
certReq.signatureAndHashes = supportedSignatureAlgorithms
|
||||||
@ -327,7 +333,7 @@ func (hs *serverHandshakeState) doFullHandshake() error {
|
|||||||
hs.finishedHash.Write(helloDone.marshal())
|
hs.finishedHash.Write(helloDone.marshal())
|
||||||
c.writeRecord(recordTypeHandshake, helloDone.marshal())
|
c.writeRecord(recordTypeHandshake, helloDone.marshal())
|
||||||
|
|
||||||
var pub *rsa.PublicKey // public key for client auth, if any
|
var pub crypto.PublicKey // public key for client auth, if any
|
||||||
|
|
||||||
msg, err := c.readHandshake()
|
msg, err := c.readHandshake()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -372,7 +378,7 @@ func (hs *serverHandshakeState) doFullHandshake() error {
|
|||||||
|
|
||||||
// If we received a client cert in response to our certificate request message,
|
// If we received a client cert in response to our certificate request message,
|
||||||
// the client will send us a certificateVerifyMsg immediately after the
|
// the client will send us a certificateVerifyMsg immediately after the
|
||||||
// clientKeyExchangeMsg. This message is a MD5SHA1 digest of all preceding
|
// clientKeyExchangeMsg. This message is a digest of all preceding
|
||||||
// handshake-layer messages that is signed using the private key corresponding
|
// handshake-layer messages that is signed using the private key corresponding
|
||||||
// to the client's certificate. This allows us to verify that the client is in
|
// to the client's certificate. This allows us to verify that the client is in
|
||||||
// possession of the private key of the certificate.
|
// possession of the private key of the certificate.
|
||||||
@ -386,8 +392,25 @@ func (hs *serverHandshakeState) doFullHandshake() error {
|
|||||||
return c.sendAlert(alertUnexpectedMessage)
|
return c.sendAlert(alertUnexpectedMessage)
|
||||||
}
|
}
|
||||||
|
|
||||||
digest, hashFunc := hs.finishedHash.hashForClientCertificate()
|
switch key := pub.(type) {
|
||||||
err = rsa.VerifyPKCS1v15(pub, hashFunc, digest, certVerify.signature)
|
case *ecdsa.PublicKey:
|
||||||
|
ecdsaSig := new(ecdsaSignature)
|
||||||
|
if _, err = asn1.Unmarshal(certVerify.signature, ecdsaSig); err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 {
|
||||||
|
err = errors.New("ECDSA signature contained zero or negative values")
|
||||||
|
break
|
||||||
|
}
|
||||||
|
digest, _ := hs.finishedHash.hashForClientCertificate(signatureECDSA)
|
||||||
|
if !ecdsa.Verify(key, digest, ecdsaSig.R, ecdsaSig.S) {
|
||||||
|
err = errors.New("ECDSA verification failure")
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case *rsa.PublicKey:
|
||||||
|
digest, hashFunc := hs.finishedHash.hashForClientCertificate(signatureRSA)
|
||||||
|
err = rsa.VerifyPKCS1v15(key, hashFunc, digest, certVerify.signature)
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.sendAlert(alertBadCertificate)
|
c.sendAlert(alertBadCertificate)
|
||||||
return errors.New("could not validate signature of connection nonces: " + err.Error())
|
return errors.New("could not validate signature of connection nonces: " + err.Error())
|
||||||
@ -507,7 +530,7 @@ func (hs *serverHandshakeState) sendFinished() error {
|
|||||||
// processCertsFromClient takes a chain of client certificates either from a
|
// processCertsFromClient takes a chain of client certificates either from a
|
||||||
// Certificates message or from a sessionState and verifies them. It returns
|
// Certificates message or from a sessionState and verifies them. It returns
|
||||||
// the public key of the leaf certificate.
|
// the public key of the leaf certificate.
|
||||||
func (hs *serverHandshakeState) processCertsFromClient(certificates [][]byte) (*rsa.PublicKey, error) {
|
func (hs *serverHandshakeState) processCertsFromClient(certificates [][]byte) (crypto.PublicKey, error) {
|
||||||
c := hs.c
|
c := hs.c
|
||||||
|
|
||||||
hs.certsFromClient = certificates
|
hs.certsFromClient = certificates
|
||||||
@ -554,8 +577,11 @@ func (hs *serverHandshakeState) processCertsFromClient(certificates [][]byte) (*
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(certs) > 0 {
|
if len(certs) > 0 {
|
||||||
pub, ok := certs[0].PublicKey.(*rsa.PublicKey)
|
var pub crypto.PublicKey
|
||||||
if !ok {
|
switch key := certs[0].PublicKey.(type) {
|
||||||
|
case *ecdsa.PublicKey, *rsa.PublicKey:
|
||||||
|
pub = key
|
||||||
|
default:
|
||||||
return nil, c.sendAlert(alertUnsupportedCertificate)
|
return nil, c.sendAlert(alertUnsupportedCertificate)
|
||||||
}
|
}
|
||||||
c.peerCertificates = certs
|
c.peerCertificates = certs
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -6,12 +6,14 @@ package tls
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto"
|
"crypto"
|
||||||
|
"crypto/ecdsa"
|
||||||
"crypto/elliptic"
|
"crypto/elliptic"
|
||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
"crypto/sha1"
|
"crypto/sha1"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
|
"encoding/asn1"
|
||||||
"errors"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"math/big"
|
"math/big"
|
||||||
@ -83,6 +85,15 @@ func (ka rsaKeyAgreement) generateClientKeyExchange(config *Config, clientHello
|
|||||||
return preMasterSecret, ckx, nil
|
return preMasterSecret, ckx, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// sha1Hash calculates a SHA1 hash over the given byte slices.
|
||||||
|
func sha1Hash(slices [][]byte) []byte {
|
||||||
|
hsha1 := sha1.New()
|
||||||
|
for _, slice := range slices {
|
||||||
|
hsha1.Write(slice)
|
||||||
|
}
|
||||||
|
return hsha1.Sum(nil)
|
||||||
|
}
|
||||||
|
|
||||||
// md5SHA1Hash implements TLS 1.0's hybrid hash function which consists of the
|
// md5SHA1Hash implements TLS 1.0's hybrid hash function which consists of the
|
||||||
// concatenation of an MD5 and SHA1 hash.
|
// concatenation of an MD5 and SHA1 hash.
|
||||||
func md5SHA1Hash(slices [][]byte) []byte {
|
func md5SHA1Hash(slices [][]byte) []byte {
|
||||||
@ -92,12 +103,7 @@ func md5SHA1Hash(slices [][]byte) []byte {
|
|||||||
hmd5.Write(slice)
|
hmd5.Write(slice)
|
||||||
}
|
}
|
||||||
copy(md5sha1, hmd5.Sum(nil))
|
copy(md5sha1, hmd5.Sum(nil))
|
||||||
|
copy(md5sha1[md5.Size:], sha1Hash(slices))
|
||||||
hsha1 := sha1.New()
|
|
||||||
for _, slice := range slices {
|
|
||||||
hsha1.Write(slice)
|
|
||||||
}
|
|
||||||
copy(md5sha1[md5.Size:], hsha1.Sum(nil))
|
|
||||||
return md5sha1
|
return md5sha1
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,24 +118,29 @@ func sha256Hash(slices [][]byte) []byte {
|
|||||||
|
|
||||||
// hashForServerKeyExchange hashes the given slices and returns their digest
|
// hashForServerKeyExchange hashes the given slices and returns their digest
|
||||||
// and the identifier of the hash function used.
|
// and the identifier of the hash function used.
|
||||||
func hashForServerKeyExchange(version uint16, slices ...[]byte) ([]byte, crypto.Hash) {
|
func hashForServerKeyExchange(sigType uint8, version uint16, slices ...[]byte) ([]byte, crypto.Hash) {
|
||||||
if version >= VersionTLS12 {
|
if version >= VersionTLS12 {
|
||||||
return sha256Hash(slices), crypto.SHA256
|
return sha256Hash(slices), crypto.SHA256
|
||||||
}
|
}
|
||||||
|
if sigType == signatureECDSA {
|
||||||
|
return sha1Hash(slices), crypto.SHA1
|
||||||
|
}
|
||||||
return md5SHA1Hash(slices), crypto.MD5SHA1
|
return md5SHA1Hash(slices), crypto.MD5SHA1
|
||||||
}
|
}
|
||||||
|
|
||||||
// ecdheRSAKeyAgreement implements a TLS key agreement where the server
|
// ecdheRSAKeyAgreement implements a TLS key agreement where the server
|
||||||
// generates a ephemeral EC public/private key pair and signs it. The
|
// generates a ephemeral EC public/private key pair and signs it. The
|
||||||
// pre-master secret is then calculated using ECDH.
|
// pre-master secret is then calculated using ECDH. The signature may
|
||||||
type ecdheRSAKeyAgreement struct {
|
// either be ECDSA or RSA.
|
||||||
|
type ecdheKeyAgreement struct {
|
||||||
version uint16
|
version uint16
|
||||||
|
sigType uint8
|
||||||
privateKey []byte
|
privateKey []byte
|
||||||
curve elliptic.Curve
|
curve elliptic.Curve
|
||||||
x, y *big.Int
|
x, y *big.Int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ka *ecdheRSAKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) {
|
func (ka *ecdheKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) {
|
||||||
var curveid uint16
|
var curveid uint16
|
||||||
|
|
||||||
Curve:
|
Curve:
|
||||||
@ -170,10 +181,30 @@ Curve:
|
|||||||
serverECDHParams[3] = byte(len(ecdhePublic))
|
serverECDHParams[3] = byte(len(ecdhePublic))
|
||||||
copy(serverECDHParams[4:], ecdhePublic)
|
copy(serverECDHParams[4:], ecdhePublic)
|
||||||
|
|
||||||
digest, hashFunc := hashForServerKeyExchange(ka.version, clientHello.random, hello.random, serverECDHParams)
|
digest, hashFunc := hashForServerKeyExchange(ka.sigType, ka.version, clientHello.random, hello.random, serverECDHParams)
|
||||||
sig, err := rsa.SignPKCS1v15(config.rand(), cert.PrivateKey.(*rsa.PrivateKey), hashFunc, digest)
|
var sig []byte
|
||||||
if err != nil {
|
switch ka.sigType {
|
||||||
return nil, errors.New("failed to sign ECDHE parameters: " + err.Error())
|
case signatureECDSA:
|
||||||
|
privKey, ok := cert.PrivateKey.(*ecdsa.PrivateKey)
|
||||||
|
if !ok {
|
||||||
|
return nil, errors.New("ECDHE ECDSA requires an ECDSA server private key")
|
||||||
|
}
|
||||||
|
r, s, err := ecdsa.Sign(config.rand(), privKey, digest)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.New("failed to sign ECDHE parameters: " + err.Error())
|
||||||
|
}
|
||||||
|
sig, err = asn1.Marshal(ecdsaSignature{r, s})
|
||||||
|
case signatureRSA:
|
||||||
|
privKey, ok := cert.PrivateKey.(*rsa.PrivateKey)
|
||||||
|
if !ok {
|
||||||
|
return nil, errors.New("ECDHE RSA requires a RSA server private key")
|
||||||
|
}
|
||||||
|
sig, err = rsa.SignPKCS1v15(config.rand(), privKey, hashFunc, digest)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.New("failed to sign ECDHE parameters: " + err.Error())
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return nil, errors.New("unknown ECDHE signature algorithm")
|
||||||
}
|
}
|
||||||
|
|
||||||
skx := new(serverKeyExchangeMsg)
|
skx := new(serverKeyExchangeMsg)
|
||||||
@ -186,7 +217,7 @@ Curve:
|
|||||||
k := skx.key[len(serverECDHParams):]
|
k := skx.key[len(serverECDHParams):]
|
||||||
if ka.version >= VersionTLS12 {
|
if ka.version >= VersionTLS12 {
|
||||||
k[0] = hashSHA256
|
k[0] = hashSHA256
|
||||||
k[1] = signatureRSA
|
k[1] = ka.sigType
|
||||||
k = k[2:]
|
k = k[2:]
|
||||||
}
|
}
|
||||||
k[0] = byte(len(sig) >> 8)
|
k[0] = byte(len(sig) >> 8)
|
||||||
@ -196,7 +227,7 @@ Curve:
|
|||||||
return skx, nil
|
return skx, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ka *ecdheRSAKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) {
|
func (ka *ecdheKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) {
|
||||||
if len(ckx.ciphertext) == 0 || int(ckx.ciphertext[0]) != len(ckx.ciphertext)-1 {
|
if len(ckx.ciphertext) == 0 || int(ckx.ciphertext[0]) != len(ckx.ciphertext)-1 {
|
||||||
return nil, errors.New("bad ClientKeyExchange")
|
return nil, errors.New("bad ClientKeyExchange")
|
||||||
}
|
}
|
||||||
@ -214,7 +245,7 @@ func (ka *ecdheRSAKeyAgreement) processClientKeyExchange(config *Config, cert *C
|
|||||||
|
|
||||||
var errServerKeyExchange = errors.New("invalid ServerKeyExchange")
|
var errServerKeyExchange = errors.New("invalid ServerKeyExchange")
|
||||||
|
|
||||||
func (ka *ecdheRSAKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error {
|
func (ka *ecdheKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error {
|
||||||
if len(skx.key) < 4 {
|
if len(skx.key) < 4 {
|
||||||
return errServerKeyExchange
|
return errServerKeyExchange
|
||||||
}
|
}
|
||||||
@ -261,11 +292,39 @@ func (ka *ecdheRSAKeyAgreement) processServerKeyExchange(config *Config, clientH
|
|||||||
}
|
}
|
||||||
sig = sig[2:]
|
sig = sig[2:]
|
||||||
|
|
||||||
digest, hashFunc := hashForServerKeyExchange(ka.version, clientHello.random, serverHello.random, serverECDHParams)
|
digest, hashFunc := hashForServerKeyExchange(ka.sigType, ka.version, clientHello.random, serverHello.random, serverECDHParams)
|
||||||
return rsa.VerifyPKCS1v15(cert.PublicKey.(*rsa.PublicKey), hashFunc, digest, sig)
|
switch ka.sigType {
|
||||||
|
case signatureECDSA:
|
||||||
|
pubKey, ok := cert.PublicKey.(*ecdsa.PublicKey)
|
||||||
|
if !ok {
|
||||||
|
return errors.New("ECDHE ECDSA requires a ECDSA server public key")
|
||||||
|
}
|
||||||
|
ecdsaSig := new(ecdsaSignature)
|
||||||
|
if _, err := asn1.Unmarshal(sig, ecdsaSig); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 {
|
||||||
|
return errors.New("ECDSA signature contained zero or negative values")
|
||||||
|
}
|
||||||
|
if !ecdsa.Verify(pubKey, digest, ecdsaSig.R, ecdsaSig.S) {
|
||||||
|
return errors.New("ECDSA verification failure")
|
||||||
|
}
|
||||||
|
case signatureRSA:
|
||||||
|
pubKey, ok := cert.PublicKey.(*rsa.PublicKey)
|
||||||
|
if !ok {
|
||||||
|
return errors.New("ECDHE RSA requires a RSA server public key")
|
||||||
|
}
|
||||||
|
if err := rsa.VerifyPKCS1v15(pubKey, hashFunc, digest, sig); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return errors.New("unknown ECDHE signature algorithm")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ka *ecdheRSAKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) {
|
func (ka *ecdheKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) {
|
||||||
if ka.curve == nil {
|
if ka.curve == nil {
|
||||||
return nil, nil, errors.New("missing ServerKeyExchange message")
|
return nil, nil, errors.New("missing ServerKeyExchange message")
|
||||||
}
|
}
|
||||||
|
@ -274,11 +274,15 @@ func (h finishedHash) serverSum(masterSecret []byte) []byte {
|
|||||||
|
|
||||||
// hashForClientCertificate returns a digest and hash function identifier
|
// hashForClientCertificate returns a digest and hash function identifier
|
||||||
// suitable for signing by a TLS client certificate.
|
// suitable for signing by a TLS client certificate.
|
||||||
func (h finishedHash) hashForClientCertificate() ([]byte, crypto.Hash) {
|
func (h finishedHash) hashForClientCertificate(sigType uint8) ([]byte, crypto.Hash) {
|
||||||
if h.version >= VersionTLS12 {
|
if h.version >= VersionTLS12 {
|
||||||
digest := h.server.Sum(nil)
|
digest := h.server.Sum(nil)
|
||||||
return digest, crypto.SHA256
|
return digest, crypto.SHA256
|
||||||
}
|
}
|
||||||
|
if sigType == signatureECDSA {
|
||||||
|
digest := h.server.Sum(nil)
|
||||||
|
return digest, crypto.SHA1
|
||||||
|
}
|
||||||
|
|
||||||
digest := make([]byte, 0, 36)
|
digest := make([]byte, 0, 36)
|
||||||
digest = h.serverMD5.Sum(digest)
|
digest = h.serverMD5.Sum(digest)
|
||||||
|
Loading…
Reference in New Issue
Block a user