nginx-ui/internal/cert/helper.go

147 lines
2.7 KiB
Go

package cert
import (
"crypto/ecdsa"
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"os"
)
func IsCertificate(pemStr string) bool {
block, _ := pem.Decode([]byte(pemStr))
if block == nil {
return false
}
_, err := x509.ParseCertificate(block.Bytes)
return err == nil
}
func IsPrivateKey(pemStr string) bool {
block, _ := pem.Decode([]byte(pemStr))
if block == nil {
return false
}
_, errRSA := x509.ParsePKCS1PrivateKey(block.Bytes)
if errRSA == nil {
return true
}
_, errECDSA := x509.ParseECPrivateKey(block.Bytes)
if errECDSA == nil {
return true
}
_, errPKC := x509.ParsePKCS8PrivateKey(block.Bytes)
return errPKC == nil
}
// IsCertificatePath checks if the file at the given path is a certificate or not exists.
func IsCertificatePath(path string) bool {
if path == "" {
return false
}
_, err := os.Stat(path)
if err != nil {
if os.IsNotExist(err) {
return true
}
return false
}
bytes, err := os.ReadFile(path)
if err != nil {
return false
}
return IsCertificate(string(bytes))
}
// IsPrivateKeyPath checks if the file at the given path is a private key or not exists.
func IsPrivateKeyPath(path string) bool {
if path == "" {
return false
}
_, err := os.Stat(path)
if err != nil {
if os.IsNotExist(err) {
return true
}
return false
}
bytes, err := os.ReadFile(path)
if err != nil {
return false
}
return IsPrivateKey(string(bytes))
}
// GetKeyType determines the key type from a PEM certificate string.
// Returns "2048", "3072", "4096", "P256", "P384" or empty string.
func GetKeyType(pemStr string) (string, error) {
block, _ := pem.Decode([]byte(pemStr))
if block == nil {
return "", ErrCertDecode
}
cert, err := x509.ParseCertificate(block.Bytes)
if err != nil {
return "", ErrCertParse
}
switch cert.PublicKeyAlgorithm {
case x509.RSA:
rsaKey, ok := cert.PublicKey.(*rsa.PublicKey)
if !ok {
return "", nil
}
keySize := rsaKey.Size() * 8 // Size returns size in bytes, convert to bits
switch keySize {
case 2048:
return "2048", nil
case 3072:
return "3072", nil
case 4096:
return "4096", nil
default:
return "", nil
}
case x509.ECDSA:
ecKey, ok := cert.PublicKey.(*ecdsa.PublicKey)
if !ok {
return "", nil
}
curve := ecKey.Curve.Params().Name
switch curve {
case "P-256":
return "P256", nil
case "P-384":
return "P384", nil
default:
return "", nil
}
default:
return "", nil
}
}
// GetKeyTypeFromPath determines the key type from a certificate file.
// Returns "2048", "3072", "4096", "P256", "P384" or empty string.
func GetKeyTypeFromPath(path string) (string, error) {
if path == "" {
return "", ErrCertPathIsEmpty
}
bytes, err := os.ReadFile(path)
if err != nil {
return "", err
}
return GetKeyType(string(bytes))
}