go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/tokenserver/appengine/impl/delegation/token.go (about) 1 // Copyright 2016 The LUCI Authors. 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 15 package delegation 16 17 import ( 18 "context" 19 "time" 20 21 "google.golang.org/protobuf/proto" 22 23 "go.chromium.org/luci/server/auth/delegation/messages" 24 "go.chromium.org/luci/server/auth/signing" 25 26 "go.chromium.org/luci/tokenserver/appengine/impl/utils/tokensigning" 27 ) 28 29 // tokenSigningContext is used to make sure delegation token is not misused in 30 // place of some other token. 31 // 32 // See SigningContext in utils/tokensigning.Signer. 33 // 34 // TODO(vadimsh): Enable it. Requires some temporary hacks to accept old and 35 // new tokens at the same time. 36 const tokenSigningContext = "" 37 38 // SignToken signs and serializes the delegation subtoken. 39 // 40 // It doesn't do any validation. Assumes the prepared subtoken is valid. 41 // 42 // Produces base64 URL-safe token or a transient error. 43 func SignToken(c context.Context, signer signing.Signer, subtok *messages.Subtoken) (string, error) { 44 s := tokensigning.Signer{ 45 Signer: signer, 46 SigningContext: tokenSigningContext, 47 Wrap: func(w *tokensigning.Unwrapped) proto.Message { 48 return &messages.DelegationToken{ 49 SerializedSubtoken: w.Body, 50 Pkcs1Sha256Sig: w.RsaSHA256Sig, 51 SignerId: "user:" + w.SignerID, 52 SigningKeyId: w.KeyID, 53 } 54 }, 55 } 56 return s.SignToken(c, subtok) 57 } 58 59 // InspectToken returns information about the delegation token. 60 // 61 // Inspection.Envelope is either nil or *messages.DelegationToken. 62 // Inspection.Body is either nil or *messages.Subtoken. 63 func InspectToken(c context.Context, certs tokensigning.CertificatesSupplier, tok string) (*tokensigning.Inspection, error) { 64 i := tokensigning.Inspector{ 65 Certificates: certs, 66 SigningContext: tokenSigningContext, 67 Envelope: func() proto.Message { return &messages.DelegationToken{} }, 68 Body: func() proto.Message { return &messages.Subtoken{} }, 69 Unwrap: func(e proto.Message) tokensigning.Unwrapped { 70 env := e.(*messages.DelegationToken) 71 return tokensigning.Unwrapped{ 72 Body: env.SerializedSubtoken, 73 RsaSHA256Sig: env.Pkcs1Sha256Sig, 74 KeyID: env.SigningKeyId, 75 } 76 }, 77 Lifespan: func(b proto.Message) tokensigning.Lifespan { 78 body := b.(*messages.Subtoken) 79 return tokensigning.Lifespan{ 80 NotBefore: time.Unix(body.CreationTime, 0), 81 NotAfter: time.Unix(body.CreationTime+int64(body.ValidityDuration), 0), 82 } 83 }, 84 } 85 return i.InspectToken(c, tok) 86 }