further changes
parent
e9696a58c2
commit
eb0b5cafce
|
@ -0,0 +1,87 @@
|
||||||
|
package routes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/hex"
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"golang.org/x/crypto/openpgp"
|
||||||
|
"golang.org/x/crypto/openpgp/armor"
|
||||||
|
"golang.org/x/crypto/openpgp/packet"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PGPKey struct {
|
||||||
|
FullName, Name, Comment, Email string
|
||||||
|
CreationTime time.Time
|
||||||
|
PublicKeyAlgorithm packet.PublicKeyAlgorithm
|
||||||
|
Fingerprint [20]byte
|
||||||
|
KeyID uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetOpenPGPInformationEncoded(c *gin.Context) {
|
||||||
|
query := c.Copy().Request.Body
|
||||||
|
|
||||||
|
block, err := armor.Decode(query)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{
|
||||||
|
"status": false,
|
||||||
|
"message": "Unable to parse body.",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
pkt := packet.NewReader(block.Body)
|
||||||
|
entity, err := openpgp.ReadEntity(pkt)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{
|
||||||
|
"status": false,
|
||||||
|
"message": "Unable to parse body.",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if len(entity.Identities) > 1 {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{
|
||||||
|
"status": false,
|
||||||
|
"message": "No identities found in PGP key.",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var key *PGPKey
|
||||||
|
for name, identity := range entity.Identities {
|
||||||
|
key = &PGPKey{
|
||||||
|
FullName: name,
|
||||||
|
Name: identity.UserId.Name,
|
||||||
|
Comment: identity.UserId.Comment,
|
||||||
|
Email: identity.UserId.Email,
|
||||||
|
CreationTime: entity.PrimaryKey.CreationTime,
|
||||||
|
PublicKeyAlgorithm: entity.PrimaryKey.PubKeyAlgo,
|
||||||
|
Fingerprint: entity.PrimaryKey.Fingerprint,
|
||||||
|
KeyID: uint16(entity.PrimaryKey.KeyId),
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
buf := new(bytes.Buffer)
|
||||||
|
closer, err := armor.Encode(buf, block.Type, block.Header)
|
||||||
|
defer closer.Close()
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{
|
||||||
|
"status": false,
|
||||||
|
"message": "Unable to re-encode armor..",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusOK, gin.H{
|
||||||
|
"status": true,
|
||||||
|
"fullName": key.FullName,
|
||||||
|
"name": key.Name,
|
||||||
|
"comment": key.Comment,
|
||||||
|
"email": key.Email,
|
||||||
|
"creationTime": key.CreationTime,
|
||||||
|
"publicKeyAlgorithm": key.PublicKeyAlgorithm,
|
||||||
|
"fingerprint": hex.EncodeToString(key.Fingerprint[:]),
|
||||||
|
"keyID": key.KeyID,
|
||||||
|
"armor": buf.String(),
|
||||||
|
})
|
||||||
|
}
|
|
@ -0,0 +1,366 @@
|
||||||
|
package routes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/ecdsa"
|
||||||
|
"crypto/ed25519"
|
||||||
|
"crypto/rsa"
|
||||||
|
"crypto/sha1"
|
||||||
|
"crypto/tls"
|
||||||
|
"crypto/x509"
|
||||||
|
"encoding/hex"
|
||||||
|
"encoding/pem"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetCertificateInformationEncoded handler function for providing raw data to be parsed
|
||||||
|
func GetCertificateInformationEncoded(c *gin.Context) {
|
||||||
|
query := c.Copy().Request.Body
|
||||||
|
data, err := ioutil.ReadAll(query)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{
|
||||||
|
"status": false,
|
||||||
|
"message": "Unable to parse body.",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
block, _ := pem.Decode(data)
|
||||||
|
if block == nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{
|
||||||
|
"status": false,
|
||||||
|
"message": "Unable to decode PEM.",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
certificate, err := x509.ParseCertificate(block.Bytes)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{
|
||||||
|
"status": false,
|
||||||
|
"message": "Unable to parse x509 data.",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var validationType string
|
||||||
|
for _, value := range certificate.PolicyIdentifiers {
|
||||||
|
if value.String() == "2.23.140.1.1" {
|
||||||
|
validationType = "EV"
|
||||||
|
} else if value.String() == "2.23.140.1.2.2" {
|
||||||
|
validationType = "OV"
|
||||||
|
} else if value.String() == "2.23.140.1.2.1" {
|
||||||
|
validationType = "DV"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
keyUsages := []int{}
|
||||||
|
keyUsagesText := []string{}
|
||||||
|
extendedKeyUsages := []int{}
|
||||||
|
extendedKeyUsagesText := []string{}
|
||||||
|
for _, value := range certificate.ExtKeyUsage {
|
||||||
|
switch value {
|
||||||
|
case 0:
|
||||||
|
// All Usages
|
||||||
|
extendedKeyUsages = append(extendedKeyUsages, 0)
|
||||||
|
extendedKeyUsagesText = append(extendedKeyUsagesText, "Any/All Usages")
|
||||||
|
break
|
||||||
|
case 1:
|
||||||
|
// TLS Web Server Authentication
|
||||||
|
extendedKeyUsages = append(extendedKeyUsages, 1)
|
||||||
|
extendedKeyUsagesText = append(extendedKeyUsagesText, "TLS Web Server Authentication")
|
||||||
|
break
|
||||||
|
case 2:
|
||||||
|
// TLS Web Client Authentication
|
||||||
|
extendedKeyUsages = append(extendedKeyUsages, 2)
|
||||||
|
extendedKeyUsagesText = append(extendedKeyUsagesText, "TLS Web Client Authentication")
|
||||||
|
break
|
||||||
|
case 3:
|
||||||
|
// Code Signing
|
||||||
|
extendedKeyUsages = append(extendedKeyUsages, 3)
|
||||||
|
extendedKeyUsagesText = append(extendedKeyUsagesText, "Code Signing")
|
||||||
|
break
|
||||||
|
case 4:
|
||||||
|
// Email Protection
|
||||||
|
extendedKeyUsages = append(extendedKeyUsages, 4)
|
||||||
|
extendedKeyUsagesText = append(extendedKeyUsagesText, "Email Protection (S/MIME)")
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if certificate.KeyUsage&x509.KeyUsageCRLSign != 0 {
|
||||||
|
keyUsages = append(keyUsages, 0)
|
||||||
|
keyUsagesText = append(keyUsagesText, "CRL Signing")
|
||||||
|
}
|
||||||
|
if certificate.KeyUsage&x509.KeyUsageCertSign != 0 {
|
||||||
|
keyUsages = append(keyUsages, 1)
|
||||||
|
keyUsagesText = append(keyUsagesText, "Certificate Signing")
|
||||||
|
}
|
||||||
|
if certificate.KeyUsage&x509.KeyUsageContentCommitment != 0 {
|
||||||
|
keyUsages = append(keyUsages, 2)
|
||||||
|
keyUsagesText = append(keyUsagesText, "Content Commitment")
|
||||||
|
}
|
||||||
|
if certificate.KeyUsage&x509.KeyUsageDataEncipherment != 0 {
|
||||||
|
keyUsages = append(keyUsages, 3)
|
||||||
|
keyUsagesText = append(keyUsagesText, "Data Encipherment")
|
||||||
|
}
|
||||||
|
if certificate.KeyUsage&x509.KeyUsageDecipherOnly != 0 {
|
||||||
|
keyUsages = append(keyUsages, 4)
|
||||||
|
keyUsagesText = append(keyUsagesText, "Decipher Only")
|
||||||
|
}
|
||||||
|
if certificate.KeyUsage&x509.KeyUsageDigitalSignature != 0 {
|
||||||
|
keyUsages = append(keyUsages, 5)
|
||||||
|
keyUsagesText = append(keyUsagesText, "Digital Signature")
|
||||||
|
}
|
||||||
|
if certificate.KeyUsage&x509.KeyUsageEncipherOnly != 0 {
|
||||||
|
keyUsages = append(keyUsages, 6)
|
||||||
|
keyUsagesText = append(keyUsagesText, "Encipher Only")
|
||||||
|
}
|
||||||
|
if certificate.KeyUsage&x509.KeyUsageKeyAgreement != 0 {
|
||||||
|
keyUsages = append(keyUsages, 7)
|
||||||
|
keyUsagesText = append(keyUsagesText, "Key Agreement")
|
||||||
|
}
|
||||||
|
if certificate.KeyUsage&x509.KeyUsageKeyEncipherment != 0 {
|
||||||
|
keyUsages = append(keyUsages, 8)
|
||||||
|
keyUsagesText = append(keyUsagesText, "Key Encipherment")
|
||||||
|
}
|
||||||
|
|
||||||
|
sum := sha1.Sum(certificate.Raw)
|
||||||
|
|
||||||
|
var bitLength int
|
||||||
|
|
||||||
|
switch certificate.PublicKeyAlgorithm {
|
||||||
|
case x509.RSA:
|
||||||
|
if rsaKey, ok := certificate.PublicKey.(*rsa.PublicKey); ok {
|
||||||
|
bitLength = rsaKey.N.BitLen()
|
||||||
|
} else {
|
||||||
|
panic("expected rsa.PublicKey for type x509.RSA")
|
||||||
|
}
|
||||||
|
case x509.ECDSA:
|
||||||
|
if ecdsaKey, ok := certificate.PublicKey.(*ecdsa.PublicKey); ok {
|
||||||
|
bitLength = ecdsaKey.Params().BitSize
|
||||||
|
} else {
|
||||||
|
panic("expected ecdsa.PublicKey for type x509.ECDSA")
|
||||||
|
}
|
||||||
|
case x509.Ed25519:
|
||||||
|
bitLength = ed25519.PublicKeySize
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, gin.H{
|
||||||
|
"status": true,
|
||||||
|
"subject": gin.H{
|
||||||
|
"commonName": certificate.Subject.CommonName,
|
||||||
|
"organization": certificate.Subject.Organization,
|
||||||
|
"organizationalUnit": certificate.Subject.OrganizationalUnit,
|
||||||
|
"locality": certificate.Subject.Locality,
|
||||||
|
"country": certificate.Subject.Country,
|
||||||
|
},
|
||||||
|
"issuer": gin.H{
|
||||||
|
"commonName": certificate.Issuer.CommonName,
|
||||||
|
"organization": certificate.Issuer.Organization,
|
||||||
|
"organizationalUnit": certificate.Issuer.OrganizationalUnit,
|
||||||
|
"locality": certificate.Issuer.Locality,
|
||||||
|
"country": certificate.Issuer.Country,
|
||||||
|
},
|
||||||
|
"aia": gin.H{
|
||||||
|
"issuingCertificateURL": certificate.IssuingCertificateURL,
|
||||||
|
"ocspServer": certificate.OCSPServer,
|
||||||
|
},
|
||||||
|
"validationType": validationType,
|
||||||
|
"signatureAlgorithm": certificate.SignatureAlgorithm.String(),
|
||||||
|
"publicKeyAlgorithm": certificate.PublicKeyAlgorithm.String(),
|
||||||
|
"serialNumber": certificate.SerialNumber.String(),
|
||||||
|
"notBefore": certificate.NotBefore,
|
||||||
|
"notAfter": certificate.NotAfter,
|
||||||
|
"keyUsage": keyUsages,
|
||||||
|
"keyUsageAsText": keyUsagesText,
|
||||||
|
"extendedKeyUsage": extendedKeyUsages,
|
||||||
|
"extendedKeyUsageAsText": extendedKeyUsagesText,
|
||||||
|
"san": certificate.DNSNames,
|
||||||
|
"emailAddresses": certificate.EmailAddresses,
|
||||||
|
"fingerprint": hex.EncodeToString(sum[:]),
|
||||||
|
"bitLength": bitLength,
|
||||||
|
"pem": string(pem.EncodeToMemory(block)),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetCertificateInfo handler
|
||||||
|
func GetCertificateInfo(c *gin.Context) {
|
||||||
|
query := c.Query("q")
|
||||||
|
resp, err := tls.Dial("tcp", query+":443", &tls.Config{InsecureSkipVerify: true, PreferServerCipherSuites: true})
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{
|
||||||
|
"status": false,
|
||||||
|
"message": "Could not establish connection with server.",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
cipherSuite := tls.CipherSuiteName(resp.ConnectionState().CipherSuite)
|
||||||
|
v := resp.ConnectionState().Version
|
||||||
|
var tlsVersion string
|
||||||
|
if v == tls.VersionSSL30 {
|
||||||
|
tlsVersion = "SSLv3"
|
||||||
|
} else if v == tls.VersionTLS10 {
|
||||||
|
tlsVersion = "TLSv1"
|
||||||
|
} else if v == tls.VersionTLS11 {
|
||||||
|
tlsVersion = "TLSv1.1"
|
||||||
|
} else if v == tls.VersionTLS12 {
|
||||||
|
tlsVersion = "TLSv1.2"
|
||||||
|
} else if v == tls.VersionTLS13 {
|
||||||
|
tlsVersion = "TLSv1.3"
|
||||||
|
} else {
|
||||||
|
tlsVersion = "unknown"
|
||||||
|
}
|
||||||
|
certificate := resp.ConnectionState().PeerCertificates[0]
|
||||||
|
rootCertificate := resp.ConnectionState().PeerCertificates[len(resp.ConnectionState().PeerCertificates)-1]
|
||||||
|
|
||||||
|
var validationType string
|
||||||
|
for _, value := range certificate.PolicyIdentifiers {
|
||||||
|
if value.String() == "2.23.140.1.1" {
|
||||||
|
validationType = "EV"
|
||||||
|
} else if value.String() == "2.23.140.1.2.2" {
|
||||||
|
validationType = "OV"
|
||||||
|
} else if value.String() == "2.23.140.1.2.1" {
|
||||||
|
validationType = "DV"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
keyUsages := []int{}
|
||||||
|
keyUsagesText := []string{}
|
||||||
|
extendedKeyUsages := []int{}
|
||||||
|
extendedKeyUsagesText := []string{}
|
||||||
|
for _, value := range certificate.ExtKeyUsage {
|
||||||
|
switch value {
|
||||||
|
case 0:
|
||||||
|
// All Usages
|
||||||
|
extendedKeyUsages = append(extendedKeyUsages, 0)
|
||||||
|
extendedKeyUsagesText = append(extendedKeyUsagesText, "Any/All Usages")
|
||||||
|
break
|
||||||
|
case 1:
|
||||||
|
// TLS Web Server Authentication
|
||||||
|
extendedKeyUsages = append(extendedKeyUsages, 1)
|
||||||
|
extendedKeyUsagesText = append(extendedKeyUsagesText, "TLS Web Server Authentication")
|
||||||
|
break
|
||||||
|
case 2:
|
||||||
|
// TLS Web Client Authentication
|
||||||
|
extendedKeyUsages = append(extendedKeyUsages, 2)
|
||||||
|
extendedKeyUsagesText = append(extendedKeyUsagesText, "TLS Web Client Authentication")
|
||||||
|
break
|
||||||
|
case 3:
|
||||||
|
// Code Signing
|
||||||
|
extendedKeyUsages = append(extendedKeyUsages, 3)
|
||||||
|
extendedKeyUsagesText = append(extendedKeyUsagesText, "Code Signing")
|
||||||
|
break
|
||||||
|
case 4:
|
||||||
|
// Email Protection
|
||||||
|
extendedKeyUsages = append(extendedKeyUsages, 4)
|
||||||
|
extendedKeyUsagesText = append(extendedKeyUsagesText, "Email Protection (S/MIME)")
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if certificate.KeyUsage&x509.KeyUsageCRLSign != 0 {
|
||||||
|
keyUsages = append(keyUsages, 0)
|
||||||
|
keyUsagesText = append(keyUsagesText, "CRL Signing")
|
||||||
|
}
|
||||||
|
if certificate.KeyUsage&x509.KeyUsageCertSign != 0 {
|
||||||
|
keyUsages = append(keyUsages, 1)
|
||||||
|
keyUsagesText = append(keyUsagesText, "Certificate Signing")
|
||||||
|
}
|
||||||
|
if certificate.KeyUsage&x509.KeyUsageContentCommitment != 0 {
|
||||||
|
keyUsages = append(keyUsages, 2)
|
||||||
|
keyUsagesText = append(keyUsagesText, "Content Commitment")
|
||||||
|
}
|
||||||
|
if certificate.KeyUsage&x509.KeyUsageDataEncipherment != 0 {
|
||||||
|
keyUsages = append(keyUsages, 3)
|
||||||
|
keyUsagesText = append(keyUsagesText, "Data Encipherment")
|
||||||
|
}
|
||||||
|
if certificate.KeyUsage&x509.KeyUsageDecipherOnly != 0 {
|
||||||
|
keyUsages = append(keyUsages, 4)
|
||||||
|
keyUsagesText = append(keyUsagesText, "Decipher Only")
|
||||||
|
}
|
||||||
|
if certificate.KeyUsage&x509.KeyUsageDigitalSignature != 0 {
|
||||||
|
keyUsages = append(keyUsages, 5)
|
||||||
|
keyUsagesText = append(keyUsagesText, "Digital Signature")
|
||||||
|
}
|
||||||
|
if certificate.KeyUsage&x509.KeyUsageEncipherOnly != 0 {
|
||||||
|
keyUsages = append(keyUsages, 6)
|
||||||
|
keyUsagesText = append(keyUsagesText, "Encipher Only")
|
||||||
|
}
|
||||||
|
if certificate.KeyUsage&x509.KeyUsageKeyAgreement != 0 {
|
||||||
|
keyUsages = append(keyUsages, 7)
|
||||||
|
keyUsagesText = append(keyUsagesText, "Key Agreement")
|
||||||
|
}
|
||||||
|
if certificate.KeyUsage&x509.KeyUsageKeyEncipherment != 0 {
|
||||||
|
keyUsages = append(keyUsages, 8)
|
||||||
|
keyUsagesText = append(keyUsagesText, "Key Encipherment")
|
||||||
|
}
|
||||||
|
|
||||||
|
sum := sha1.Sum(certificate.Raw)
|
||||||
|
|
||||||
|
var bitLength int
|
||||||
|
|
||||||
|
switch certificate.PublicKeyAlgorithm {
|
||||||
|
case x509.RSA:
|
||||||
|
if rsaKey, ok := certificate.PublicKey.(*rsa.PublicKey); ok {
|
||||||
|
bitLength = rsaKey.N.BitLen()
|
||||||
|
} else {
|
||||||
|
panic("expected rsa.PublicKey for type x509.RSA")
|
||||||
|
}
|
||||||
|
case x509.ECDSA:
|
||||||
|
if ecdsaKey, ok := certificate.PublicKey.(*ecdsa.PublicKey); ok {
|
||||||
|
bitLength = ecdsaKey.Params().BitSize
|
||||||
|
} else {
|
||||||
|
panic("expected ecdsa.PublicKey for type x509.ECDSA")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, gin.H{
|
||||||
|
"status": true,
|
||||||
|
"subject": gin.H{
|
||||||
|
"commonName": certificate.Subject.CommonName,
|
||||||
|
"organization": certificate.Subject.Organization,
|
||||||
|
"organizationalUnit": certificate.Subject.OrganizationalUnit,
|
||||||
|
"locality": certificate.Subject.Locality,
|
||||||
|
"country": certificate.Subject.Country,
|
||||||
|
},
|
||||||
|
"issuer": gin.H{
|
||||||
|
"commonName": certificate.Issuer.CommonName,
|
||||||
|
"organization": certificate.Issuer.Organization,
|
||||||
|
"organizationalUnit": certificate.Issuer.OrganizationalUnit,
|
||||||
|
"locality": certificate.Issuer.Locality,
|
||||||
|
"country": certificate.Issuer.Country,
|
||||||
|
},
|
||||||
|
"root": gin.H{
|
||||||
|
"commonName": rootCertificate.Issuer.CommonName,
|
||||||
|
"organization": rootCertificate.Issuer.Organization,
|
||||||
|
"organizationalUnit": rootCertificate.Issuer.OrganizationalUnit,
|
||||||
|
"locality": rootCertificate.Issuer.Locality,
|
||||||
|
"country": rootCertificate.Issuer.Country,
|
||||||
|
},
|
||||||
|
"aia": gin.H{
|
||||||
|
"issuingCertificateURL": certificate.IssuingCertificateURL,
|
||||||
|
"ocspServer": certificate.OCSPServer,
|
||||||
|
},
|
||||||
|
"validationType": validationType,
|
||||||
|
"signatureAlgorithm": certificate.SignatureAlgorithm.String(),
|
||||||
|
"publicKeyAlgorithm": certificate.PublicKeyAlgorithm.String(),
|
||||||
|
"serialNumber": certificate.SerialNumber.String(),
|
||||||
|
"notBefore": certificate.NotBefore,
|
||||||
|
"notAfter": certificate.NotAfter,
|
||||||
|
"keyUsage": keyUsages,
|
||||||
|
"keyUsageAsText": keyUsagesText,
|
||||||
|
"extendedKeyUsage": extendedKeyUsages,
|
||||||
|
"extendedKeyUsageAsText": extendedKeyUsagesText,
|
||||||
|
"san": certificate.DNSNames,
|
||||||
|
"emailAddresses": certificate.EmailAddresses,
|
||||||
|
"fingerprint": hex.EncodeToString(sum[:]),
|
||||||
|
"bitLength": bitLength,
|
||||||
|
"connection": gin.H{
|
||||||
|
"tlsVersion": tlsVersion,
|
||||||
|
"cipherSuite": cipherSuite,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
Loading…
Reference in New Issue