Remove BPA from Makefile
[icn.git] / cmd / bpa-operator / vendor / golang.org / x / crypto / ssh / certs.go
1 // Copyright 2012 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 ssh
6
7 import (
8         "bytes"
9         "errors"
10         "fmt"
11         "io"
12         "net"
13         "sort"
14         "time"
15 )
16
17 // These constants from [PROTOCOL.certkeys] represent the algorithm names
18 // for certificate types supported by this package.
19 const (
20         CertAlgoRSAv01      = "ssh-rsa-cert-v01@openssh.com"
21         CertAlgoDSAv01      = "ssh-dss-cert-v01@openssh.com"
22         CertAlgoECDSA256v01 = "ecdsa-sha2-nistp256-cert-v01@openssh.com"
23         CertAlgoECDSA384v01 = "ecdsa-sha2-nistp384-cert-v01@openssh.com"
24         CertAlgoECDSA521v01 = "ecdsa-sha2-nistp521-cert-v01@openssh.com"
25         CertAlgoED25519v01  = "ssh-ed25519-cert-v01@openssh.com"
26 )
27
28 // Certificate types distinguish between host and user
29 // certificates. The values can be set in the CertType field of
30 // Certificate.
31 const (
32         UserCert = 1
33         HostCert = 2
34 )
35
36 // Signature represents a cryptographic signature.
37 type Signature struct {
38         Format string
39         Blob   []byte
40 }
41
42 // CertTimeInfinity can be used for OpenSSHCertV01.ValidBefore to indicate that
43 // a certificate does not expire.
44 const CertTimeInfinity = 1<<64 - 1
45
46 // An Certificate represents an OpenSSH certificate as defined in
47 // [PROTOCOL.certkeys]?rev=1.8. The Certificate type implements the
48 // PublicKey interface, so it can be unmarshaled using
49 // ParsePublicKey.
50 type Certificate struct {
51         Nonce           []byte
52         Key             PublicKey
53         Serial          uint64
54         CertType        uint32
55         KeyId           string
56         ValidPrincipals []string
57         ValidAfter      uint64
58         ValidBefore     uint64
59         Permissions
60         Reserved     []byte
61         SignatureKey PublicKey
62         Signature    *Signature
63 }
64
65 // genericCertData holds the key-independent part of the certificate data.
66 // Overall, certificates contain an nonce, public key fields and
67 // key-independent fields.
68 type genericCertData struct {
69         Serial          uint64
70         CertType        uint32
71         KeyId           string
72         ValidPrincipals []byte
73         ValidAfter      uint64
74         ValidBefore     uint64
75         CriticalOptions []byte
76         Extensions      []byte
77         Reserved        []byte
78         SignatureKey    []byte
79         Signature       []byte
80 }
81
82 func marshalStringList(namelist []string) []byte {
83         var to []byte
84         for _, name := range namelist {
85                 s := struct{ N string }{name}
86                 to = append(to, Marshal(&s)...)
87         }
88         return to
89 }
90
91 type optionsTuple struct {
92         Key   string
93         Value []byte
94 }
95
96 type optionsTupleValue struct {
97         Value string
98 }
99
100 // serialize a map of critical options or extensions
101 // issue #10569 - per [PROTOCOL.certkeys] and SSH implementation,
102 // we need two length prefixes for a non-empty string value
103 func marshalTuples(tups map[string]string) []byte {
104         keys := make([]string, 0, len(tups))
105         for key := range tups {
106                 keys = append(keys, key)
107         }
108         sort.Strings(keys)
109
110         var ret []byte
111         for _, key := range keys {
112                 s := optionsTuple{Key: key}
113                 if value := tups[key]; len(value) > 0 {
114                         s.Value = Marshal(&optionsTupleValue{value})
115                 }
116                 ret = append(ret, Marshal(&s)...)
117         }
118         return ret
119 }
120
121 // issue #10569 - per [PROTOCOL.certkeys] and SSH implementation,
122 // we need two length prefixes for a non-empty option value
123 func parseTuples(in []byte) (map[string]string, error) {
124         tups := map[string]string{}
125         var lastKey string
126         var haveLastKey bool
127
128         for len(in) > 0 {
129                 var key, val, extra []byte
130                 var ok bool
131
132                 if key, in, ok = parseString(in); !ok {
133                         return nil, errShortRead
134                 }
135                 keyStr := string(key)
136                 // according to [PROTOCOL.certkeys], the names must be in
137                 // lexical order.
138                 if haveLastKey && keyStr <= lastKey {
139                         return nil, fmt.Errorf("ssh: certificate options are not in lexical order")
140                 }
141                 lastKey, haveLastKey = keyStr, true
142                 // the next field is a data field, which if non-empty has a string embedded
143                 if val, in, ok = parseString(in); !ok {
144                         return nil, errShortRead
145                 }
146                 if len(val) > 0 {
147                         val, extra, ok = parseString(val)
148                         if !ok {
149                                 return nil, errShortRead
150                         }
151                         if len(extra) > 0 {
152                                 return nil, fmt.Errorf("ssh: unexpected trailing data after certificate option value")
153                         }
154                         tups[keyStr] = string(val)
155                 } else {
156                         tups[keyStr] = ""
157                 }
158         }
159         return tups, nil
160 }
161
162 func parseCert(in []byte, privAlgo string) (*Certificate, error) {
163         nonce, rest, ok := parseString(in)
164         if !ok {
165                 return nil, errShortRead
166         }
167
168         key, rest, err := parsePubKey(rest, privAlgo)
169         if err != nil {
170                 return nil, err
171         }
172
173         var g genericCertData
174         if err := Unmarshal(rest, &g); err != nil {
175                 return nil, err
176         }
177
178         c := &Certificate{
179                 Nonce:       nonce,
180                 Key:         key,
181                 Serial:      g.Serial,
182                 CertType:    g.CertType,
183                 KeyId:       g.KeyId,
184                 ValidAfter:  g.ValidAfter,
185                 ValidBefore: g.ValidBefore,
186         }
187
188         for principals := g.ValidPrincipals; len(principals) > 0; {
189                 principal, rest, ok := parseString(principals)
190                 if !ok {
191                         return nil, errShortRead
192                 }
193                 c.ValidPrincipals = append(c.ValidPrincipals, string(principal))
194                 principals = rest
195         }
196
197         c.CriticalOptions, err = parseTuples(g.CriticalOptions)
198         if err != nil {
199                 return nil, err
200         }
201         c.Extensions, err = parseTuples(g.Extensions)
202         if err != nil {
203                 return nil, err
204         }
205         c.Reserved = g.Reserved
206         k, err := ParsePublicKey(g.SignatureKey)
207         if err != nil {
208                 return nil, err
209         }
210
211         c.SignatureKey = k
212         c.Signature, rest, ok = parseSignatureBody(g.Signature)
213         if !ok || len(rest) > 0 {
214                 return nil, errors.New("ssh: signature parse error")
215         }
216
217         return c, nil
218 }
219
220 type openSSHCertSigner struct {
221         pub    *Certificate
222         signer Signer
223 }
224
225 type algorithmOpenSSHCertSigner struct {
226         *openSSHCertSigner
227         algorithmSigner AlgorithmSigner
228 }
229
230 // NewCertSigner returns a Signer that signs with the given Certificate, whose
231 // private key is held by signer. It returns an error if the public key in cert
232 // doesn't match the key used by signer.
233 func NewCertSigner(cert *Certificate, signer Signer) (Signer, error) {
234         if bytes.Compare(cert.Key.Marshal(), signer.PublicKey().Marshal()) != 0 {
235                 return nil, errors.New("ssh: signer and cert have different public key")
236         }
237
238         if algorithmSigner, ok := signer.(AlgorithmSigner); ok {
239                 return &algorithmOpenSSHCertSigner{
240                         &openSSHCertSigner{cert, signer}, algorithmSigner}, nil
241         } else {
242                 return &openSSHCertSigner{cert, signer}, nil
243         }
244 }
245
246 func (s *openSSHCertSigner) Sign(rand io.Reader, data []byte) (*Signature, error) {
247         return s.signer.Sign(rand, data)
248 }
249
250 func (s *openSSHCertSigner) PublicKey() PublicKey {
251         return s.pub
252 }
253
254 func (s *algorithmOpenSSHCertSigner) SignWithAlgorithm(rand io.Reader, data []byte, algorithm string) (*Signature, error) {
255         return s.algorithmSigner.SignWithAlgorithm(rand, data, algorithm)
256 }
257
258 const sourceAddressCriticalOption = "source-address"
259
260 // CertChecker does the work of verifying a certificate. Its methods
261 // can be plugged into ClientConfig.HostKeyCallback and
262 // ServerConfig.PublicKeyCallback. For the CertChecker to work,
263 // minimally, the IsAuthority callback should be set.
264 type CertChecker struct {
265         // SupportedCriticalOptions lists the CriticalOptions that the
266         // server application layer understands. These are only used
267         // for user certificates.
268         SupportedCriticalOptions []string
269
270         // IsUserAuthority should return true if the key is recognized as an
271         // authority for the given user certificate. This allows for
272         // certificates to be signed by other certificates. This must be set
273         // if this CertChecker will be checking user certificates.
274         IsUserAuthority func(auth PublicKey) bool
275
276         // IsHostAuthority should report whether the key is recognized as
277         // an authority for this host. This allows for certificates to be
278         // signed by other keys, and for those other keys to only be valid
279         // signers for particular hostnames. This must be set if this
280         // CertChecker will be checking host certificates.
281         IsHostAuthority func(auth PublicKey, address string) bool
282
283         // Clock is used for verifying time stamps. If nil, time.Now
284         // is used.
285         Clock func() time.Time
286
287         // UserKeyFallback is called when CertChecker.Authenticate encounters a
288         // public key that is not a certificate. It must implement validation
289         // of user keys or else, if nil, all such keys are rejected.
290         UserKeyFallback func(conn ConnMetadata, key PublicKey) (*Permissions, error)
291
292         // HostKeyFallback is called when CertChecker.CheckHostKey encounters a
293         // public key that is not a certificate. It must implement host key
294         // validation or else, if nil, all such keys are rejected.
295         HostKeyFallback HostKeyCallback
296
297         // IsRevoked is called for each certificate so that revocation checking
298         // can be implemented. It should return true if the given certificate
299         // is revoked and false otherwise. If nil, no certificates are
300         // considered to have been revoked.
301         IsRevoked func(cert *Certificate) bool
302 }
303
304 // CheckHostKey checks a host key certificate. This method can be
305 // plugged into ClientConfig.HostKeyCallback.
306 func (c *CertChecker) CheckHostKey(addr string, remote net.Addr, key PublicKey) error {
307         cert, ok := key.(*Certificate)
308         if !ok {
309                 if c.HostKeyFallback != nil {
310                         return c.HostKeyFallback(addr, remote, key)
311                 }
312                 return errors.New("ssh: non-certificate host key")
313         }
314         if cert.CertType != HostCert {
315                 return fmt.Errorf("ssh: certificate presented as a host key has type %d", cert.CertType)
316         }
317         if !c.IsHostAuthority(cert.SignatureKey, addr) {
318                 return fmt.Errorf("ssh: no authorities for hostname: %v", addr)
319         }
320
321         hostname, _, err := net.SplitHostPort(addr)
322         if err != nil {
323                 return err
324         }
325
326         // Pass hostname only as principal for host certificates (consistent with OpenSSH)
327         return c.CheckCert(hostname, cert)
328 }
329
330 // Authenticate checks a user certificate. Authenticate can be used as
331 // a value for ServerConfig.PublicKeyCallback.
332 func (c *CertChecker) Authenticate(conn ConnMetadata, pubKey PublicKey) (*Permissions, error) {
333         cert, ok := pubKey.(*Certificate)
334         if !ok {
335                 if c.UserKeyFallback != nil {
336                         return c.UserKeyFallback(conn, pubKey)
337                 }
338                 return nil, errors.New("ssh: normal key pairs not accepted")
339         }
340
341         if cert.CertType != UserCert {
342                 return nil, fmt.Errorf("ssh: cert has type %d", cert.CertType)
343         }
344         if !c.IsUserAuthority(cert.SignatureKey) {
345                 return nil, fmt.Errorf("ssh: certificate signed by unrecognized authority")
346         }
347
348         if err := c.CheckCert(conn.User(), cert); err != nil {
349                 return nil, err
350         }
351
352         return &cert.Permissions, nil
353 }
354
355 // CheckCert checks CriticalOptions, ValidPrincipals, revocation, timestamp and
356 // the signature of the certificate.
357 func (c *CertChecker) CheckCert(principal string, cert *Certificate) error {
358         if c.IsRevoked != nil && c.IsRevoked(cert) {
359                 return fmt.Errorf("ssh: certificate serial %d revoked", cert.Serial)
360         }
361
362         for opt := range cert.CriticalOptions {
363                 // sourceAddressCriticalOption will be enforced by
364                 // serverAuthenticate
365                 if opt == sourceAddressCriticalOption {
366                         continue
367                 }
368
369                 found := false
370                 for _, supp := range c.SupportedCriticalOptions {
371                         if supp == opt {
372                                 found = true
373                                 break
374                         }
375                 }
376                 if !found {
377                         return fmt.Errorf("ssh: unsupported critical option %q in certificate", opt)
378                 }
379         }
380
381         if len(cert.ValidPrincipals) > 0 {
382                 // By default, certs are valid for all users/hosts.
383                 found := false
384                 for _, p := range cert.ValidPrincipals {
385                         if p == principal {
386                                 found = true
387                                 break
388                         }
389                 }
390                 if !found {
391                         return fmt.Errorf("ssh: principal %q not in the set of valid principals for given certificate: %q", principal, cert.ValidPrincipals)
392                 }
393         }
394
395         clock := c.Clock
396         if clock == nil {
397                 clock = time.Now
398         }
399
400         unixNow := clock().Unix()
401         if after := int64(cert.ValidAfter); after < 0 || unixNow < int64(cert.ValidAfter) {
402                 return fmt.Errorf("ssh: cert is not yet valid")
403         }
404         if before := int64(cert.ValidBefore); cert.ValidBefore != uint64(CertTimeInfinity) && (unixNow >= before || before < 0) {
405                 return fmt.Errorf("ssh: cert has expired")
406         }
407         if err := cert.SignatureKey.Verify(cert.bytesForSigning(), cert.Signature); err != nil {
408                 return fmt.Errorf("ssh: certificate signature does not verify")
409         }
410
411         return nil
412 }
413
414 // SignCert sets c.SignatureKey to the authority's public key and stores a
415 // Signature, by authority, in the certificate.
416 func (c *Certificate) SignCert(rand io.Reader, authority Signer) error {
417         c.Nonce = make([]byte, 32)
418         if _, err := io.ReadFull(rand, c.Nonce); err != nil {
419                 return err
420         }
421         c.SignatureKey = authority.PublicKey()
422
423         sig, err := authority.Sign(rand, c.bytesForSigning())
424         if err != nil {
425                 return err
426         }
427         c.Signature = sig
428         return nil
429 }
430
431 var certAlgoNames = map[string]string{
432         KeyAlgoRSA:      CertAlgoRSAv01,
433         KeyAlgoDSA:      CertAlgoDSAv01,
434         KeyAlgoECDSA256: CertAlgoECDSA256v01,
435         KeyAlgoECDSA384: CertAlgoECDSA384v01,
436         KeyAlgoECDSA521: CertAlgoECDSA521v01,
437         KeyAlgoED25519:  CertAlgoED25519v01,
438 }
439
440 // certToPrivAlgo returns the underlying algorithm for a certificate algorithm.
441 // Panics if a non-certificate algorithm is passed.
442 func certToPrivAlgo(algo string) string {
443         for privAlgo, pubAlgo := range certAlgoNames {
444                 if pubAlgo == algo {
445                         return privAlgo
446                 }
447         }
448         panic("unknown cert algorithm")
449 }
450
451 func (cert *Certificate) bytesForSigning() []byte {
452         c2 := *cert
453         c2.Signature = nil
454         out := c2.Marshal()
455         // Drop trailing signature length.
456         return out[:len(out)-4]
457 }
458
459 // Marshal serializes c into OpenSSH's wire format. It is part of the
460 // PublicKey interface.
461 func (c *Certificate) Marshal() []byte {
462         generic := genericCertData{
463                 Serial:          c.Serial,
464                 CertType:        c.CertType,
465                 KeyId:           c.KeyId,
466                 ValidPrincipals: marshalStringList(c.ValidPrincipals),
467                 ValidAfter:      uint64(c.ValidAfter),
468                 ValidBefore:     uint64(c.ValidBefore),
469                 CriticalOptions: marshalTuples(c.CriticalOptions),
470                 Extensions:      marshalTuples(c.Extensions),
471                 Reserved:        c.Reserved,
472                 SignatureKey:    c.SignatureKey.Marshal(),
473         }
474         if c.Signature != nil {
475                 generic.Signature = Marshal(c.Signature)
476         }
477         genericBytes := Marshal(&generic)
478         keyBytes := c.Key.Marshal()
479         _, keyBytes, _ = parseString(keyBytes)
480         prefix := Marshal(&struct {
481                 Name  string
482                 Nonce []byte
483                 Key   []byte `ssh:"rest"`
484         }{c.Type(), c.Nonce, keyBytes})
485
486         result := make([]byte, 0, len(prefix)+len(genericBytes))
487         result = append(result, prefix...)
488         result = append(result, genericBytes...)
489         return result
490 }
491
492 // Type returns the key name. It is part of the PublicKey interface.
493 func (c *Certificate) Type() string {
494         algo, ok := certAlgoNames[c.Key.Type()]
495         if !ok {
496                 panic("unknown cert key type " + c.Key.Type())
497         }
498         return algo
499 }
500
501 // Verify verifies a signature against the certificate's public
502 // key. It is part of the PublicKey interface.
503 func (c *Certificate) Verify(data []byte, sig *Signature) error {
504         return c.Key.Verify(data, sig)
505 }
506
507 func parseSignatureBody(in []byte) (out *Signature, rest []byte, ok bool) {
508         format, in, ok := parseString(in)
509         if !ok {
510                 return
511         }
512
513         out = &Signature{
514                 Format: string(format),
515         }
516
517         if out.Blob, in, ok = parseString(in); !ok {
518                 return
519         }
520
521         return out, in, ok
522 }
523
524 func parseSignature(in []byte) (out *Signature, rest []byte, ok bool) {
525         sigBytes, rest, ok := parseString(in)
526         if !ok {
527                 return
528         }
529
530         out, trailing, ok := parseSignatureBody(sigBytes)
531         if !ok || len(trailing) > 0 {
532                 return nil, nil, false
533         }
534         return
535 }