コード例 #1
0
ファイル: host.go プロジェクト: jemacom/hydra
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
}
コード例 #2
0
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

}
コード例 #3
0
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

}
コード例 #4
0
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)
}
コード例 #5
0
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
}