package main
import (
"crypto/x509"
"encoding/pem"
"fmt"
"os"
"strings" // Added this package for string manipulation
"github.com/joho/godotenv"
"github.com/golang-jwt/jwt"
"golang.org/x/crypto/ed25519"
)
// loadEnvVars loads environment variables from .env file
func loadEnvVars() error {
err := godotenv.Load()
if err != nil {
return fmt.Errorf("error loading .env file: %w", err)
}
return nil
}
// getPublicKey retrieves the public key from an environment variable
func getPublicKey() (ed25519.PublicKey, error) {
publicPEM := os.Getenv("JWT_PUBLIC_KEY")
if publicPEM == "" {
return nil, fmt.Errorf("Environment variable for public key is not set")
}
// Convert single-line PEM to multi-line PEM if needed
publicPEM = strings.Replace(publicPEM, "-----BEGIN PUBLIC KEY-----", "-----BEGIN PUBLIC KEY-----\n", 1)
publicPEM = strings.Replace(publicPEM, "-----END PUBLIC KEY-----", "\n-----END PUBLIC KEY-----", 1)
block, _ := pem.Decode([]byte(publicPEM))
if block == nil {
return nil, fmt.Errorf("Failed to parse PEM block containing the public key")
}
pubKey, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
return nil, fmt.Errorf("Failed to parse public key: %w", err)
}
ed25519PubKey, ok := pubKey.(ed25519.PublicKey)
if !ok {
return nil, fmt.Errorf("Failed to convert public key to Ed25519 public key")
}
return ed25519PubKey, nil
}
// validateJWT validates the JWT token
func validateJWT(ed25519PubKey ed25519.PublicKey, jwtToken, expectedAudience string) error {
token, err := jwt.Parse(jwtToken, func(token *jwt.Token) (interface{}, error) {
return ed25519PubKey, nil
})
if err != nil {
return fmt.Errorf("Failed to parse JWT token: %w", err)
}
// Print the JWT headers
fmt.Println("JWT Headers:", token.Header)
if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
audience, audienceOk := claims["aud"].(string)
if audienceOk && audience == expectedAudience {
fmt.Println("Decoded Payload:", claims)
fmt.Println("Signature is valid.")
return nil
} else {
return fmt.Errorf("Invalid Token: Invalid audience")
}
} else {
return fmt.Errorf("Invalid Token: Token is not valid")
}
}
func main() {
err := loadEnvVars()
if err != nil {
fmt.Printf("Error occurred: %v\n", err)
return
}
ed25519PubKey, err := getPublicKey()
if err != nil {
fmt.Printf("Error occurred: %v\n", err)
return
}
// Add the JWT to validate
jwtToken := "JWT_TO_VALIDATE"
expectedAudience := "YOUR_COOL_APP"
err = validateJWT(ed25519PubKey, jwtToken, expectedAudience)
if err != nil {
fmt.Printf("Error occurred: %v\n", err)
return
}
}