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  }