customer/internal/service/encrypt/encrypt.go
2023-05-16 04:12:34 +03:00

104 lines
3.0 KiB
Go

package encrypt
import (
"crypto/ed25519"
"crypto/x509"
"encoding/pem"
"fmt"
"penahub.gitlab.yandexcloud.net/pena-services/pena-social-auth/internal/models"
)
//go:generate mockery --name jwtUtil
type jwtUtil interface {
Validate(string) (*models.JWTAuthUser, error)
}
type ServiceDeps struct {
JWT jwtUtil
/* Публичный ключ для верификации подписи кривой Эдвардса (Edwards curve) */
PublicCurveKey string
/* Приватный ключ для верификации подписи кривой Эдвардса (Edwards curve) */
PrivateCurveKey string
/*
Обший секретный знаменатель для шифрования и верификации подписи
(должен быть одинаковым для всех микросервисов)
*/
SignSecret string
}
type Service struct {
jwt jwtUtil
publicCurveKey string
privateCurveKey string
signSecret string
}
func New(deps *ServiceDeps) *Service {
return &Service{
jwt: deps.JWT,
publicCurveKey: deps.PublicCurveKey,
privateCurveKey: deps.PrivateCurveKey,
signSecret: deps.SignSecret,
}
}
func (receiver *Service) VerifySignature(signature []byte) (isValid bool, err error) {
defer func() {
if recovered := recover(); recovered != nil {
err = fmt.Errorf("recovered sign error on <VerifySignature> of <EncryptService>: %v", recovered)
}
}()
block, _ := pem.Decode([]byte(receiver.publicCurveKey))
if block == nil {
return false, fmt.Errorf("public key block is nil")
}
rawPublicKey, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
return false, fmt.Errorf("failed parse public key on <VerifySignature> of <EncryptService>: %w", err)
}
publicKey, ok := rawPublicKey.(ed25519.PublicKey)
if !ok {
return false, fmt.Errorf("failed convert to ed25519.PrivateKey on <VerifySignature> of <EncryptService>: %w", err)
}
return ed25519.Verify(publicKey, []byte(receiver.signSecret), signature), nil
}
func (receiver *Service) SignCommonSecret() (signature []byte, err error) {
defer func() {
if recovered := recover(); recovered != nil {
err = fmt.Errorf("recovered sign error on <SignCommonSecret> of <EncryptService>: %v", recovered)
}
}()
block, _ := pem.Decode([]byte(receiver.privateCurveKey))
rawPrivateKey, err := x509.ParsePKCS8PrivateKey(block.Bytes)
if err != nil {
return []byte{}, fmt.Errorf("failed parse private key on <SignCommonSecret> of <EncryptService>: %w", err)
}
privateKey, ok := rawPrivateKey.(ed25519.PrivateKey)
if !ok {
return []byte{}, fmt.Errorf("failed convert to ed25519.PrivateKey on <SignCommonSecret> of <EncryptService>: %w", err)
}
return ed25519.Sign(privateKey, []byte(receiver.signSecret)), nil
}
func (receiver *Service) VerifyJWT(token string) (string, error) {
validatedJwtPayload, err := receiver.jwt.Validate(token)
if err != nil {
return "", fmt.Errorf("failed to verify jwt on <VerifyJWT> of <EncryptService>: %w", err)
}
return validatedJwtPayload.ID, nil
}