func getOrCreateTLSCertificate(cmd *cobra.Command) tls.Certificate { if cert := loadCertificateFromFile(cmd); cert != nil { return *cert } else if cert := loadCertificateFromEnv(cmd); cert != nil { return *cert } ctx := c.Context() keys, err := ctx.KeyManager.GetKey(TLSKeyName, "private") if errors.Is(err, pkg.ErrNotFound) { logrus.Warn("Key for TLS not found. Creating new one.") keys, err = new(jwk.ECDSA256Generator).Generate("") pkg.Must(err, "Could not generate key: %s", err) cert, err := createSelfSignedCertificate(jwk.First(keys.Key("private")).Key) pkg.Must(err, "Could not create X509 PEM Key Pair: %s", err) private := jwk.First(keys.Key("private")) private.Certificates = []*x509.Certificate{cert} keys = &jose.JsonWebKeySet{ Keys: []jose.JsonWebKey{ *private, *jwk.First(keys.Key("public")), }, } err = ctx.KeyManager.AddKeySet(TLSKeyName, keys) pkg.Must(err, "Could not persist key: %s", err) } else { pkg.Must(err, "Could not retrieve key: %s", err) } private := jwk.First(keys.Key("private")) block, err := jwk.PEMBlockForKey(private.Key) if err != nil { pkg.Must(err, "Could not encode key to PEM: %s", err) } if len(private.Certificates) == 0 { logrus.Fatal("TLS certificate chain can not be empty") } pemCert := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: private.Certificates[0].Raw}) pemKey := pem.EncodeToMemory(block) cert, err := tls.X509KeyPair(pemCert, pemKey) pkg.Must(err, "Could not decode certificate: %s", err) return cert }
func (s *DefaultConsentStrategy) IssueChallenge(authorizeRequest fosite.AuthorizeRequester, redirectURL string) (string, error) { token := jwt.New(jwt.SigningMethodRS256) token.Claims = map[string]interface{}{ "jti": uuid.New(), "scp": authorizeRequest.GetScopes(), "aud": authorizeRequest.GetClient().GetID(), "exp": time.Now().Add(time.Hour).Unix(), "redir": redirectURL, } ks, err := s.KeyManager.GetKey(ConsentChallengeKey, "private") if err != nil { return "", errors.New(err) } rsaKey, ok := jwk.First(ks.Keys).Key.(*rsa.PrivateKey) if !ok { return "", errors.New("Could not convert to RSA Private Key") } var signature, encoded string if encoded, err = token.SigningString(); err != nil { return "", errors.New(err) } else if signature, err = token.Method.Sign(encoded, rsaKey); err != nil { return "", errors.New(err) } return fmt.Sprintf("%s.%s", encoded, signature), nil }
func (s *DefaultConsentStrategy) ValidateResponse(a fosite.AuthorizeRequester, token string) (claims *Session, err error) { t, err := jwt.Parse(token, func(t *jwt.Token) (interface{}, error) { if _, ok := t.Method.(*jwt.SigningMethodRSA); !ok { return nil, errors.Errorf("Unexpected signing method: %v", t.Header["alg"]) } pk, err := s.KeyManager.GetKey(ConsentEndpointKey, "public") if err != nil { return nil, err } rsaKey, ok := jwk.First(pk.Keys).Key.(*rsa.PublicKey) if !ok { return nil, errors.New("Could not convert to RSA Private Key") } return rsaKey, nil }) if err != nil { return nil, errors.Errorf("Couldn't parse token: %v", err) } else if !t.Valid { return nil, errors.Errorf("Token is invalid") } if time.Now().After(ejwt.ToTime(t.Claims["exp"])) { return nil, errors.Errorf("Token expired") } if ejwt.ToString(t.Claims["aud"]) != a.GetClient().GetID() { return nil, errors.Errorf("Audience mismatch") } subject := ejwt.ToString(t.Claims["sub"]) for _, scope := range toStringSlice(t.Claims["scp"]) { a.GrantScope(scope) } return &Session{ Subject: subject, DefaultSession: &strategy.DefaultSession{ Claims: &ejwt.IDTokenClaims{ Audience: a.GetClient().GetID(), Subject: subject, Issuer: s.Issuer, IssuedAt: time.Now(), ExpiresAt: time.Now(), Extra: t.Claims, }, Headers: &ejwt.Headers{}, }, }, err }
func TestAuthCode(t *testing.T) { var code string var validConsent bool router.GET("/consent", func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { tok, err := jwt.Parse(r.URL.Query().Get("challenge"), func(tt *jwt.Token) (interface{}, error) { if _, ok := tt.Method.(*jwt.SigningMethodRSA); !ok { return nil, errors.Errorf("Unexpected signing method: %v", tt.Header["alg"]) } pk, err := keyManager.GetKey(ConsentChallengeKey, "public") pkg.RequireError(t, false, err) return jwk.MustRSAPublic(jwk.First(pk.Keys)), nil }) pkg.RequireError(t, false, err) require.True(t, tok.Valid) consent, err := signConsentToken(map[string]interface{}{ "jti": uuid.New(), "exp": time.Now().Add(time.Hour).Unix(), "iat": time.Now().Unix(), "aud": "app-client", }) pkg.RequireError(t, false, err) http.Redirect(w, r, ejwt.ToString(tok.Claims["redir"])+"&consent="+consent, http.StatusFound) validConsent = true }) router.GET("/callback", func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { code = r.URL.Query().Get("code") w.Write([]byte(r.URL.Query().Get("code"))) }) resp, err := http.Get(oauthConfig.AuthCodeURL("some-foo-state")) pkg.RequireError(t, false, err) defer resp.Body.Close() _, err = ioutil.ReadAll(resp.Body) pkg.RequireError(t, false, err) require.True(t, validConsent) require.NotEmpty(t, code) _, err = oauthConfig.Exchange(oauth2.NoContext, code) pkg.RequireError(t, false, err) }
func signConsentToken(claims map[string]interface{}) (string, error) { token := jwt.New(jwt.SigningMethodRS256) token.Claims = claims keys, err := keyManager.GetKey(ConsentEndpointKey, "private") if err != nil { return "", errors.New(err) } rsaKey, err := jwk.ToRSAPrivate(jwk.First(keys.Keys)) if err != nil { return "", err } var signature, encoded string if encoded, err = token.SigningString(); err != nil { return "", errors.New(err) } else if signature, err = token.Method.Sign(encoded, rsaKey); err != nil { return "", errors.New(err) } return fmt.Sprintf("%s.%s", encoded, signature), nil }