github.com/zmap/zcrypto@v0.0.0-20240512203510-0fef58d9a9db/tls/tls_ka.go (about) 1 // Copyright 2015 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package tls 6 7 import ( 8 "encoding/json" 9 "math/big" 10 "regexp" 11 "strconv" 12 13 jsonKeys "github.com/zmap/zcrypto/json" 14 ) 15 16 // SignatureAndHash is a SigAndHash that implements json.Marshaler and 17 // json.Unmarshaler 18 type SignatureAndHash SigAndHash 19 20 type auxSignatureAndHash struct { 21 SignatureAlgorithm string `json:"signature_algorithm"` 22 HashAlgorithm string `json:"hash_algorithm"` 23 } 24 25 // MarshalJSON implements the json.Marshaler interface 26 func (sh *SignatureAndHash) MarshalJSON() ([]byte, error) { 27 aux := auxSignatureAndHash{ 28 SignatureAlgorithm: nameForSignature(sh.Signature), 29 HashAlgorithm: nameForHash(sh.Hash), 30 } 31 return json.Marshal(&aux) 32 } 33 34 var unknownAlgorithmRegex = regexp.MustCompile(`unknown\.(\d+)`) 35 36 // UnmarshalJSON implements the json.Unmarshaler interface 37 func (sh *SignatureAndHash) UnmarshalJSON(b []byte) error { 38 aux := new(auxSignatureAndHash) 39 if err := json.Unmarshal(b, aux); err != nil { 40 return err 41 } 42 sh.Signature = signatureToName(aux.SignatureAlgorithm) 43 sh.Hash = hashToName(aux.HashAlgorithm) 44 return nil 45 } 46 47 func (ka *rsaKeyAgreement) RSAParams() *jsonKeys.RSAPublicKey { 48 out := new(jsonKeys.RSAPublicKey) 49 out.PublicKey = ka.publicKey 50 return out 51 } 52 53 func (ka *ecdheKeyAgreement) ECDHParams() *jsonKeys.ECDHParams { 54 out := new(jsonKeys.ECDHParams) 55 out.TLSCurveID = jsonKeys.TLSCurveID(ka.curveID) 56 out.ServerPublic = &jsonKeys.ECPoint{} 57 if ka.x != nil { 58 out.ServerPublic.X = new(big.Int) 59 out.ServerPublic.X.Set(ka.x) 60 } 61 if ka.y != nil { 62 out.ServerPublic.Y = new(big.Int) 63 out.ServerPublic.Y.Set(ka.y) 64 } 65 if len(ka.serverPrivKey) > 0 { 66 out.ServerPrivate = new(jsonKeys.ECDHPrivateParams) 67 out.ServerPrivate.Length = len(ka.serverPrivKey) 68 out.ServerPrivate.Value = make([]byte, len(ka.serverPrivKey)) 69 copy(out.ServerPrivate.Value, ka.serverPrivKey) 70 } 71 return out 72 } 73 74 func (ka *ecdheKeyAgreement) ClientECDHParams() *jsonKeys.ECDHParams { 75 out := new(jsonKeys.ECDHParams) 76 out.TLSCurveID = jsonKeys.TLSCurveID(ka.curveID) 77 out.ClientPublic = &jsonKeys.ECPoint{} 78 if ka.clientX != nil { 79 out.ClientPublic.X = new(big.Int) 80 out.ClientPublic.X.Set(ka.clientX) 81 } 82 if ka.clientY != nil { 83 out.ClientPublic.Y = new(big.Int) 84 out.ClientPublic.Y.Set(ka.clientY) 85 } 86 87 if len(ka.clientPrivKey) > 0 { 88 out.ClientPrivate = new(jsonKeys.ECDHPrivateParams) 89 out.ClientPrivate.Length = len(ka.clientPrivKey) 90 out.ClientPrivate.Value = make([]byte, len(ka.clientPrivKey)) 91 copy(out.ClientPrivate.Value, ka.clientPrivKey) 92 } 93 return out 94 } 95 96 func (ka *dheKeyAgreement) DHParams() *jsonKeys.DHParams { 97 out := new(jsonKeys.DHParams) 98 if ka.p != nil { 99 out.Prime = new(big.Int).Set(ka.p) 100 } 101 if ka.g != nil { 102 out.Generator = new(big.Int).Set(ka.g) 103 } 104 if ka.yServer != nil { 105 out.ServerPublic = new(big.Int).Set(ka.yServer) 106 if ka.yOurs != nil && ka.xOurs != nil && ka.yServer.Cmp(ka.yOurs) == 0 { 107 out.ServerPrivate = new(big.Int).Set(ka.xOurs) 108 } 109 } 110 return out 111 } 112 113 func (ka *dheKeyAgreement) ClientDHParams() *jsonKeys.DHParams { 114 out := new(jsonKeys.DHParams) 115 if ka.p != nil { 116 out.Prime = new(big.Int).Set(ka.p) 117 } 118 if ka.g != nil { 119 out.Generator = new(big.Int).Set(ka.g) 120 } 121 if ka.yClient != nil { 122 out.ClientPublic = new(big.Int).Set(ka.yClient) 123 if ka.yOurs != nil && ka.xOurs != nil && ka.yClient.Cmp(ka.yOurs) == 0 { 124 out.ClientPrivate = new(big.Int).Set(ka.xOurs) 125 } 126 } 127 return out 128 } 129 130 // DigitalSignature represents a signature for a digitally-signed-struct in the 131 // TLS record protocol. It is dependent on the version of TLS in use. In TLS 132 // 1.2, the first two bytes of the signature specify the signature and hash 133 // algorithms. These are contained the TLSSignature.Raw field, but also parsed 134 // out into TLSSignature.SigHashExtension. In older versions of TLS, the 135 // signature and hash extension is not used, and so 136 // TLSSignature.SigHashExtension will be empty. The version string is stored in 137 // TLSSignature.TLSVersion. 138 type DigitalSignature struct { 139 Raw []byte `json:"raw"` 140 Type string `json:"type,omitempty"` 141 Valid bool `json:"valid"` 142 SigHashExtension *SignatureAndHash `json:"signature_and_hash_type,omitempty"` 143 Version TLSVersion `json:"tls_version"` 144 } 145 146 func signatureTypeToName(sigType uint8) string { 147 switch sigType { 148 case signatureRSA: 149 return "rsa" 150 case signatureDSA: 151 return "dsa" 152 case signatureECDSA: 153 return "ecdsa" 154 default: 155 break 156 } 157 return "unknown." + strconv.Itoa(int(sigType)) 158 } 159 160 func (ka *signedKeyAgreement) Signature() *DigitalSignature { 161 out := DigitalSignature{ 162 Raw: ka.raw, 163 Type: signatureTypeToName(ka.sigType), 164 Valid: ka.valid, 165 Version: TLSVersion(ka.version), 166 } 167 if ka.version >= VersionTLS12 { 168 out.SigHashExtension = new(SignatureAndHash) 169 *out.SigHashExtension = SignatureAndHash(ka.sh) 170 } 171 return &out 172 }