Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: server/auth/delegation/checker.go

Issue 2386643003: auth: Make luci-go services trust signatures produced by the token server. (Closed)
Patch Set: add tests Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « server/auth/authtest/db.go ('k') | server/auth/delegation/checker_test.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The LUCI Authors. All rights reserved. 1 // Copyright 2016 The LUCI Authors. All rights reserved.
2 // Use of this source code is governed under the Apache License, Version 2.0 2 // Use of this source code is governed under the Apache License, Version 2.0
3 // that can be found in the LICENSE file. 3 // that can be found in the LICENSE file.
4 4
5 package delegation 5 package delegation
6 6
7 import ( 7 import (
8 "encoding/base64" 8 "encoding/base64"
9 "fmt" 9 "fmt"
10 "strings" 10 "strings"
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
43 // verified. 43 // verified.
44 ErrUnsignedDelegationToken = errors.New("auth: unsigned delegation token ") 44 ErrUnsignedDelegationToken = errors.New("auth: unsigned delegation token ")
45 45
46 // ErrForbiddenDelegationToken is returned if token is structurally corr ect, 46 // ErrForbiddenDelegationToken is returned if token is structurally corr ect,
47 // but some of its constraints prevents it from being used. For example, it is 47 // but some of its constraints prevents it from being used. For example, it is
48 // already expired or it was minted for some other services, etc. See lo gs for 48 // already expired or it was minted for some other services, etc. See lo gs for
49 // details. 49 // details.
50 ErrForbiddenDelegationToken = errors.New("auth: forbidden delegation tok en") 50 ErrForbiddenDelegationToken = errors.New("auth: forbidden delegation tok en")
51 ) 51 )
52 52
53 // CertificatesProvider is accepted by 'CheckToken'. 53 // CertificatesProvider is used by 'CheckToken', it is implemented by authdb.DB.
54 //
55 // It returns certificates of services trusted to sign tokens.
54 type CertificatesProvider interface { 56 type CertificatesProvider interface {
55 » // GetAuthServiceCertificates returns a bundle with certificates of a pr imary 57 » // GetCertificates returns a bundle with certificates of a trusted signe r.
56 » // auth service. 58 » //
57 » GetAuthServiceCertificates(c context.Context) (*signing.PublicCertificat es, error) 59 » // Returns (nil, nil) if the given signer is not trusted.
60 » //
61 » // Returns errors (usually transient) if the bundle can't be fetched.
62 » GetCertificates(c context.Context, id identity.Identity) (*signing.Publi cCertificates, error)
58 } 63 }
59 64
60 // GroupsChecker is accepted by 'CheckToken'. 65 // GroupsChecker is accepted by 'CheckToken', it is implemented by authdb.DB.
61 type GroupsChecker interface { 66 type GroupsChecker interface {
62 // IsMember returns true if the given identity belongs to the given grou p. 67 // IsMember returns true if the given identity belongs to the given grou p.
63 // 68 //
64 // Unknown groups are considered empty. May return errors if underlying 69 // Unknown groups are considered empty. May return errors if underlying
65 // datastore has issues. 70 // datastore has issues.
66 IsMember(c context.Context, id identity.Identity, group string) (bool, e rror) 71 IsMember(c context.Context, id identity.Identity, group string) (bool, e rror)
67 } 72 }
68 73
69 // CheckTokenParams is passed to CheckToken. 74 // CheckTokenParams is passed to CheckToken.
70 type CheckTokenParams struct { 75 type CheckTokenParams struct {
71 Token string // the delegation token to che ck 76 Token string // the delegation token to che ck
72 PeerID identity.Identity // identity of the caller, as extracted from its credentials 77 PeerID identity.Identity // identity of the caller, as extracted from its credentials
73 » CertificatesProvider CertificatesProvider // returns auth service certif icates 78 » CertificatesProvider CertificatesProvider // returns certificates with t rusted keys
74 GroupsChecker GroupsChecker // knows how to do group looku ps 79 GroupsChecker GroupsChecker // knows how to do group looku ps
75 OwnServiceIdentity identity.Identity // identity of the current ser vice 80 OwnServiceIdentity identity.Identity // identity of the current ser vice
76 } 81 }
77 82
78 // CheckToken verifies validity of a delegation token. 83 // CheckToken verifies validity of a delegation token.
79 // 84 //
80 // If the token is valid, it returns the delegated identity (embedded in the 85 // If the token is valid, it returns the delegated identity (embedded in the
81 // token). 86 // token).
82 // 87 //
83 // May return transient errors. 88 // May return transient errors.
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
119 if err = proto.Unmarshal(blob, tok); err != nil { 124 if err = proto.Unmarshal(blob, tok); err != nil {
120 return nil, err 125 return nil, err
121 } 126 }
122 return tok, nil 127 return tok, nil
123 } 128 }
124 129
125 // unsealToken verifies token's signature and deserializes the subtoken. 130 // unsealToken verifies token's signature and deserializes the subtoken.
126 // 131 //
127 // May return transient errors. 132 // May return transient errors.
128 func unsealToken(c context.Context, tok *messages.DelegationToken, certsProvider CertificatesProvider) (*messages.Subtoken, error) { 133 func unsealToken(c context.Context, tok *messages.DelegationToken, certsProvider CertificatesProvider) (*messages.Subtoken, error) {
129 » // Grab the public keys of the primary auth service. It is the service t hat 134 » // Grab the public keys of the service that signed the token, if we trus t it.
130 » // signs tokens. 135 » signerID, err := identity.MakeIdentity(tok.SignerId)
131 » //
132 » // TODO(vadimsh): There's 'signer_id' field in the DelegationToken proto . We
133 » // ignore it for now. If we ever support multiple trusted signers, we'd need
134 » // to start using it to pick the correct public key. For now only the ce ntral
135 » // auth service is trusted, so we just grab its certs.
136 » certs, err := certsProvider.GetAuthServiceCertificates(c)
137 if err != nil { 136 if err != nil {
138 » » return nil, err 137 » » return nil, fmt.Errorf("bad signer_id %q - %s", tok.SignerId, er r)
138 » }
139 » certs, err := certsProvider.GetCertificates(c, signerID)
140 » switch {
141 » case err != nil:
142 » » return nil, fmt.Errorf("failed to grab certificates of %q - %s", tok.SignerId, err)
143 » case certs == nil:
144 » » return nil, fmt.Errorf("the signer %q is not trusted", tok.Signe rId)
139 } 145 }
140 146
141 // Check the signature on the token. 147 // Check the signature on the token.
142 err = certs.CheckSignature(tok.SigningKeyId, tok.SerializedSubtoken, tok .Pkcs1Sha256Sig) 148 err = certs.CheckSignature(tok.SigningKeyId, tok.SerializedSubtoken, tok .Pkcs1Sha256Sig)
143 if err != nil { 149 if err != nil {
144 return nil, err 150 return nil, err
145 } 151 }
146 152
147 // The signature is correct! Deserialize the subtoken. 153 // The signature is correct! Deserialize the subtoken.
148 msg := &messages.Subtoken{} 154 msg := &messages.Subtoken{}
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 switch ok, err := checker.IsMember(c, ident, strings.Tri mPrefix(aud, "group:")); { 255 switch ok, err := checker.IsMember(c, ident, strings.Tri mPrefix(aud, "group:")); {
250 case err != nil: 256 case err != nil:
251 return err // transient error during group looku p 257 return err // transient error during group looku p
252 case ok: 258 case ok:
253 return nil // success, 'ident' is in the target audience 259 return nil // success, 'ident' is in the target audience
254 } 260 }
255 } 261 }
256 } 262 }
257 return fmt.Errorf("%s is not allowed to use the token", ident) 263 return fmt.Errorf("%s is not allowed to use the token", ident)
258 } 264 }
OLDNEW
« no previous file with comments | « server/auth/authtest/db.go ('k') | server/auth/delegation/checker_test.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698