1// Copyright 2016 Google LLC. All Rights Reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package tls
16
17import (
18	"crypto"
19	"crypto/dsa"
20	"crypto/ecdsa"
21	"crypto/rsa"
22	"fmt"
23)
24
25// DigitallySigned gives information about a signature, including the algorithm used
26// and the signature value.  Defined in RFC 5246 s4.7.
27type DigitallySigned struct {
28	Algorithm SignatureAndHashAlgorithm
29	Signature []byte `tls:"minlen:0,maxlen:65535"`
30}
31
32func (d DigitallySigned) String() string {
33	return fmt.Sprintf("Signature: HashAlgo=%v SignAlgo=%v Value=%x", d.Algorithm.Hash, d.Algorithm.Signature, d.Signature)
34}
35
36// SignatureAndHashAlgorithm gives information about the algorithms used for a
37// signature.  Defined in RFC 5246 s7.4.1.4.1.
38type SignatureAndHashAlgorithm struct {
39	Hash      HashAlgorithm      `tls:"maxval:255"`
40	Signature SignatureAlgorithm `tls:"maxval:255"`
41}
42
43// HashAlgorithm enum from RFC 5246 s7.4.1.4.1.
44type HashAlgorithm Enum
45
46// HashAlgorithm constants from RFC 5246 s7.4.1.4.1.
47const (
48	None   HashAlgorithm = 0
49	MD5    HashAlgorithm = 1
50	SHA1   HashAlgorithm = 2
51	SHA224 HashAlgorithm = 3
52	SHA256 HashAlgorithm = 4
53	SHA384 HashAlgorithm = 5
54	SHA512 HashAlgorithm = 6
55)
56
57func (h HashAlgorithm) String() string {
58	switch h {
59	case None:
60		return "None"
61	case MD5:
62		return "MD5"
63	case SHA1:
64		return "SHA1"
65	case SHA224:
66		return "SHA224"
67	case SHA256:
68		return "SHA256"
69	case SHA384:
70		return "SHA384"
71	case SHA512:
72		return "SHA512"
73	default:
74		return fmt.Sprintf("UNKNOWN(%d)", h)
75	}
76}
77
78// SignatureAlgorithm enum from RFC 5246 s7.4.1.4.1.
79type SignatureAlgorithm Enum
80
81// SignatureAlgorithm constants from RFC 5246 s7.4.1.4.1.
82const (
83	Anonymous SignatureAlgorithm = 0
84	RSA       SignatureAlgorithm = 1
85	DSA       SignatureAlgorithm = 2
86	ECDSA     SignatureAlgorithm = 3
87)
88
89func (s SignatureAlgorithm) String() string {
90	switch s {
91	case Anonymous:
92		return "Anonymous"
93	case RSA:
94		return "RSA"
95	case DSA:
96		return "DSA"
97	case ECDSA:
98		return "ECDSA"
99	default:
100		return fmt.Sprintf("UNKNOWN(%d)", s)
101	}
102}
103
104// SignatureAlgorithmFromPubKey returns the algorithm used for this public key.
105// ECDSA, RSA, and DSA keys are supported. Other key types will return Anonymous.
106func SignatureAlgorithmFromPubKey(k crypto.PublicKey) SignatureAlgorithm {
107	switch k.(type) {
108	case *ecdsa.PublicKey:
109		return ECDSA
110	case *rsa.PublicKey:
111		return RSA
112	case *dsa.PublicKey:
113		return DSA
114	default:
115		return Anonymous
116	}
117}
118