feat: add more code and features
This commit is contained in:
44
integrity.go
Normal file
44
integrity.go
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/ecdsa"
|
||||||
|
"crypto/ed25519"
|
||||||
|
"crypto/rsa"
|
||||||
|
"crypto/x509"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
|
func checkPublicKey(cert *x509.Certificate) {
|
||||||
|
switch pub := cert.PublicKey.(type) {
|
||||||
|
|
||||||
|
case *rsa.PublicKey:
|
||||||
|
fmt.Println("RSA key:", pub.N.BitLen(), "bits")
|
||||||
|
case *ecdsa.PublicKey:
|
||||||
|
fmt.Println("ECDSA key:", pub.Curve.Params().Name)
|
||||||
|
case ed25519.PublicKey:
|
||||||
|
fmt.Println("Ed25519 key")
|
||||||
|
default:
|
||||||
|
log.Fatal("Unsupported public key type")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkCertKeyPair(certPub any, priv any) bool {
|
||||||
|
switch pub := certPub.(type) {
|
||||||
|
|
||||||
|
case *rsa.PublicKey:
|
||||||
|
privRSA, ok := priv.(*rsa.PrivateKey)
|
||||||
|
return ok && pub.N.Cmp(privRSA.N) == 0 && pub.E == privRSA.E
|
||||||
|
|
||||||
|
case *ecdsa.PublicKey:
|
||||||
|
privECDSA, ok := priv.(*ecdsa.PrivateKey)
|
||||||
|
return ok && pub.X.Cmp(privECDSA.X) == 0 && pub.Y.Cmp(privECDSA.Y) == 0
|
||||||
|
|
||||||
|
case ed25519.PublicKey:
|
||||||
|
privEd, ok := priv.(ed25519.PrivateKey)
|
||||||
|
return ok && pub.Equal(privEd.Public().(ed25519.PublicKey))
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
256
main.go
256
main.go
@@ -1,99 +1,195 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"crypto/x509"
|
||||||
"os"
|
"encoding/pem"
|
||||||
"fyne.io/fyne/v2"
|
"fmt"
|
||||||
"fyne.io/fyne/v2/app"
|
"log"
|
||||||
"fyne.io/fyne/v2/container"
|
"os"
|
||||||
"fyne.io/fyne/v2/dialog"
|
"slices"
|
||||||
"fyne.io/fyne/v2/widget"
|
|
||||||
"fyne.io/fyne/v2/layout"
|
"fyne.io/fyne/v2"
|
||||||
|
"fyne.io/fyne/v2/app"
|
||||||
|
"fyne.io/fyne/v2/container"
|
||||||
|
"fyne.io/fyne/v2/dialog"
|
||||||
|
"fyne.io/fyne/v2/layout"
|
||||||
|
"fyne.io/fyne/v2/widget"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
a := app.New()
|
a := app.NewWithID("nl.systemec.pfxgen")
|
||||||
w := a.NewWindow("Upload 3 Files")
|
w := a.NewWindow("Systemec PKCS12-Generator")
|
||||||
w.Resize(fyne.NewSize(800, 400))
|
w.Resize(fyne.NewSize(600, 400))
|
||||||
|
|
||||||
var file1Path, file2Path, file3Path string
|
var keyPath, certPath string
|
||||||
|
|
||||||
// Labels to show selected filenames
|
// Labels to show selected filenames
|
||||||
fileLabel1 := widget.NewLabel("No file selected")
|
fileLabel1 := widget.NewLabel("No file selected")
|
||||||
fileLabel2 := widget.NewLabel("No file selected")
|
fileLabel2 := widget.NewLabel("No file selected")
|
||||||
fileLabel3 := widget.NewLabel("No file selected")
|
|
||||||
|
|
||||||
// Button 1
|
radioLabel1 := widget.NewLabel("Select which Sectigo Intermediate")
|
||||||
btn1 := widget.NewButton("Upload Certificate Private Key File", func() {
|
|
||||||
dialog.ShowFileOpen(func(r fyne.URIReadCloser, err error) {
|
|
||||||
if r != nil {
|
|
||||||
fileLabel1.SetText(r.URI().Name())
|
|
||||||
file1Path = r.URI().Path()
|
|
||||||
}
|
|
||||||
}, w)
|
|
||||||
})
|
|
||||||
|
|
||||||
// Button 2
|
// Certificate Keyfile
|
||||||
btn2 := widget.NewButton("Upload Certificate File", func() {
|
btn1 := widget.NewButton("Upload Private Key File", func() {
|
||||||
dialog.ShowFileOpen(func(r fyne.URIReadCloser, err error) {
|
dialog.ShowFileOpen(func(r fyne.URIReadCloser, err error) {
|
||||||
if r != nil {
|
if r != nil {
|
||||||
fileLabel2.SetText(r.URI().Name())
|
fileLabel1.SetText(r.URI().Name())
|
||||||
file2Path = r.URI().Path()
|
keyPath = r.URI().Path()
|
||||||
}
|
}
|
||||||
}, w)
|
}, w)
|
||||||
})
|
})
|
||||||
|
|
||||||
// Button 3
|
// Certificate file
|
||||||
btn3 := widget.NewButton("Upload Certificate Intermediate File", func() {
|
btn2 := widget.NewButton("Upload Certificate File", func() {
|
||||||
dialog.ShowFileOpen(func(r fyne.URIReadCloser, err error) {
|
dialog.ShowFileOpen(func(r fyne.URIReadCloser, err error) {
|
||||||
if r != nil {
|
if r != nil {
|
||||||
fileLabel3.SetText(r.URI().Name())
|
fileLabel2.SetText(r.URI().Name())
|
||||||
file3Path = r.URI().Path()
|
certPath = r.URI().Path()
|
||||||
}
|
}
|
||||||
}, w)
|
}, w)
|
||||||
})
|
})
|
||||||
|
|
||||||
goBtn := widget.NewButton("Go", func() {
|
// Certificate Intermediate
|
||||||
fmt.Println("Go button clicked")
|
var newSectigoSelected bool
|
||||||
files := []string{file1Path, file2Path, file3Path}
|
caRadio := widget.NewRadioGroup([]string{"New Sectigo (2025+)", "Old Sectigo (2025-)"}, func(selected string) {
|
||||||
|
switch selected {
|
||||||
|
case "New Sectigo (2025+)":
|
||||||
|
newSectigoSelected = true
|
||||||
|
case "Old Sectigo (2025-)":
|
||||||
|
newSectigoSelected = false
|
||||||
|
default: //Fallback
|
||||||
|
newSectigoSelected = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
caRadio.SetSelected("New Sectigo (2025+)") // default
|
||||||
|
|
||||||
allPresent := true
|
entry := widget.NewEntry()
|
||||||
for _, f := range files {
|
entry.SetPlaceHolder("")
|
||||||
if f == "" {
|
entry.Disable()
|
||||||
allPresent = false
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !allPresent {
|
actionBtn := widget.NewButton("Generate PKCS12 (pfx)", func() {
|
||||||
fmt.Println("One or more files missing!")
|
files := []string{keyPath, certPath}
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, f := range files {
|
var caCert string
|
||||||
data, err := os.ReadFile(f)
|
if newSectigoSelected {
|
||||||
if err != nil {
|
caCert = sectigoNew
|
||||||
fmt.Printf("Error reading file %d (%s): %v\n", i+1, f, err)
|
} else {
|
||||||
continue
|
caCert = sectigoOld
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("Contents of file %d (%s):\n%s\n\n", i+1, f, string(data))
|
allPresent := true
|
||||||
}
|
if slices.Contains(files, "") {
|
||||||
})
|
allPresent = false
|
||||||
|
}
|
||||||
|
|
||||||
content := container.NewBorder(
|
if !allPresent {
|
||||||
nil, // top
|
fmt.Println("One or more files missing!")
|
||||||
goBtn, // bottom
|
return
|
||||||
nil, nil, // left, right
|
}
|
||||||
container.NewVBox( // center content
|
|
||||||
widget.NewLabel("Select 3 files:"),
|
|
||||||
container.NewHBox(btn1, fileLabel1),
|
|
||||||
container.NewHBox(btn2, fileLabel2),
|
|
||||||
container.NewHBox(btn3, fileLabel3),
|
|
||||||
layout.NewSpacer(), // adds flexible space
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
w.SetContent(content)
|
entry.SetText(integrityCheckAndGo(keyPath, certPath, caCert))
|
||||||
w.ShowAndRun()
|
})
|
||||||
|
|
||||||
|
cancelBtn := widget.NewButton("Exit", func() {
|
||||||
|
fmt.Println("Quitting...")
|
||||||
|
os.Exit(0)
|
||||||
|
})
|
||||||
|
|
||||||
|
// CREATE LAYOUTS
|
||||||
|
|
||||||
|
bottom := container.NewHBox(
|
||||||
|
actionBtn, // left
|
||||||
|
layout.NewSpacer(), // flexible space
|
||||||
|
cancelBtn, // right
|
||||||
|
)
|
||||||
|
|
||||||
|
centerContent := container.NewVBox(
|
||||||
|
widget.NewLabel("Select relevant files."),
|
||||||
|
container.New(layout.NewGridLayout(2), btn1, fileLabel1),
|
||||||
|
container.New(layout.NewGridLayout(2), btn2, fileLabel2),
|
||||||
|
layout.NewSpacer(),
|
||||||
|
container.New(layout.NewGridLayout(2), radioLabel1, caRadio),
|
||||||
|
layout.NewSpacer(), // optional flexible space
|
||||||
|
entry, // just add the entry directly
|
||||||
|
)
|
||||||
|
|
||||||
|
content := container.NewBorder(
|
||||||
|
nil, // top
|
||||||
|
bottom, // bottom
|
||||||
|
nil, nil, // left, right
|
||||||
|
centerContent,
|
||||||
|
)
|
||||||
|
|
||||||
|
w.SetContent(content)
|
||||||
|
w.ShowAndRun()
|
||||||
|
}
|
||||||
|
|
||||||
|
func readFile(path string) []byte {
|
||||||
|
rawData, err := os.ReadFile(path)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Error reading contents of %s, %e", path, err)
|
||||||
|
return nil
|
||||||
|
} else {
|
||||||
|
return rawData
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func parsePrivateKey(keyData []byte) any {
|
||||||
|
block, _ := pem.Decode(keyData)
|
||||||
|
if block == nil {
|
||||||
|
log.Fatal("failed to decode key PEM")
|
||||||
|
}
|
||||||
|
|
||||||
|
privateKey, err := x509.ParsePKCS8PrivateKey(block.Bytes)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return privateKey
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseX509(certData []byte) *x509.Certificate {
|
||||||
|
block, _ := pem.Decode(certData)
|
||||||
|
if block == nil {
|
||||||
|
log.Fatal("failed to parse PEM block")
|
||||||
|
}
|
||||||
|
|
||||||
|
cert, err := x509.ParseCertificate(block.Bytes)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
return cert
|
||||||
|
}
|
||||||
|
|
||||||
|
func integrityCheckAndGo(keyPath, certPath, caCertString string) string {
|
||||||
|
if _, err := os.Stat(keyPath); err != nil {
|
||||||
|
fmt.Printf("Error checking Private Keyfile, %e", err)
|
||||||
|
return "Error..."
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := os.Stat(certPath); err != nil {
|
||||||
|
fmt.Printf("Error checking Certificate file, %e", err)
|
||||||
|
return "Error..."
|
||||||
|
}
|
||||||
|
|
||||||
|
keyData := readFile(keyPath) // Read the private key file (PEM/DER)
|
||||||
|
certData := readFile(certPath) // Read the certificate file (PEM/DER)
|
||||||
|
|
||||||
|
key := parsePrivateKey(keyData) // Convert bytes to Go private key object
|
||||||
|
cert := parseX509(certData) // Convert bytes to Go x509.Certificate
|
||||||
|
caCert := parseX509([]byte(caCertString))
|
||||||
|
|
||||||
|
checkPublicKey(cert) // Print the information about the key
|
||||||
|
|
||||||
|
if checkCertKeyPair(cert.PublicKey, key) {
|
||||||
|
fmt.Println("Private key matches certificate")
|
||||||
|
} else {
|
||||||
|
fmt.Println("Private key does NOT match certificate")
|
||||||
|
}
|
||||||
|
|
||||||
|
return generatePKCS12(key, cert, caCert)
|
||||||
|
}
|
||||||
|
|
||||||
|
func generatePKCS12(pKey any, cert, caCert *x509.Certificate) string {
|
||||||
|
return "Nice"
|
||||||
}
|
}
|
||||||
|
|||||||
74
sectigo_certificates.go
Normal file
74
sectigo_certificates.go
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
const sectigoNew string = `-----BEGIN CERTIFICATE-----
|
||||||
|
MIIGTDCCBDSgAwIBAgIQOXpmzCdWNi4NqofKbqvjsTANBgkqhkiG9w0BAQwFADBf
|
||||||
|
MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQD
|
||||||
|
Ey1TZWN0aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBSNDYw
|
||||||
|
HhcNMjEwMzIyMDAwMDAwWhcNMzYwMzIxMjM1OTU5WjBgMQswCQYDVQQGEwJHQjEY
|
||||||
|
MBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTcwNQYDVQQDEy5TZWN0aWdvIFB1Ymxp
|
||||||
|
YyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gQ0EgRFYgUjM2MIIBojANBgkqhkiG9w0B
|
||||||
|
AQEFAAOCAY8AMIIBigKCAYEAljZf2HIz7+SPUPQCQObZYcrxLTHYdf1ZtMRe7Yeq
|
||||||
|
RPSwygz16qJ9cAWtWNTcuICc++p8Dct7zNGxCpqmEtqifO7NvuB5dEVexXn9RFFH
|
||||||
|
12Hm+NtPRQgXIFjx6MSJcNWuVO3XGE57L1mHlcQYj+g4hny90aFh2SCZCDEVkAja
|
||||||
|
EMMfYPKuCjHuuF+bzHFb/9gV8P9+ekcHENF2nR1efGWSKwnfG5RawlkaQDpRtZTm
|
||||||
|
M64TIsv/r7cyFO4nSjs1jLdXYdz5q3a4L0NoabZfbdxVb+CUEHfB0bpulZQtH1Rv
|
||||||
|
38e/lIdP7OTTIlZh6OYL6NhxP8So0/sht/4J9mqIGxRFc0/pC8suja+wcIUna0HB
|
||||||
|
pXKfXTKpzgis+zmXDL06ASJf5E4A2/m+Hp6b84sfPAwQ766rI65mh50S0Di9E3Pn
|
||||||
|
2WcaJc+PILsBmYpgtmgWTR9eV9otfKRUBfzHUHcVgarub/XluEpRlTtZudU5xbFN
|
||||||
|
xx/DgMrXLUAPaI60fZ6wA+PTAgMBAAGjggGBMIIBfTAfBgNVHSMEGDAWgBRWc1hk
|
||||||
|
lfmSGrASKgRieaFAFYghSTAdBgNVHQ4EFgQUaMASFhgOr872h6YyV6NGUV3LBycw
|
||||||
|
DgYDVR0PAQH/BAQDAgGGMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0lBBYwFAYI
|
||||||
|
KwYBBQUHAwEGCCsGAQUFBwMCMBsGA1UdIAQUMBIwBgYEVR0gADAIBgZngQwBAgEw
|
||||||
|
VAYDVR0fBE0wSzBJoEegRYZDaHR0cDovL2NybC5zZWN0aWdvLmNvbS9TZWN0aWdv
|
||||||
|
UHVibGljU2VydmVyQXV0aGVudGljYXRpb25Sb290UjQ2LmNybDCBhAYIKwYBBQUH
|
||||||
|
AQEEeDB2ME8GCCsGAQUFBzAChkNodHRwOi8vY3J0LnNlY3RpZ28uY29tL1NlY3Rp
|
||||||
|
Z29QdWJsaWNTZXJ2ZXJBdXRoZW50aWNhdGlvblJvb3RSNDYucDdjMCMGCCsGAQUF
|
||||||
|
BzABhhdodHRwOi8vb2NzcC5zZWN0aWdvLmNvbTANBgkqhkiG9w0BAQwFAAOCAgEA
|
||||||
|
YtOC9Fy+TqECFw40IospI92kLGgoSZGPOSQXMBqmsGWZUQ7rux7cj1du6d9rD6C8
|
||||||
|
ze1B2eQjkrGkIL/OF1s7vSmgYVafsRoZd/IHUrkoQvX8FZwUsmPu7amgBfaY3g+d
|
||||||
|
q1x0jNGKb6I6Bzdl6LgMD9qxp+3i7GQOnd9J8LFSietY6Z4jUBzVoOoz8iAU84OF
|
||||||
|
h2HhAuiPw1ai0VnY38RTI+8kepGWVfGxfBWzwH9uIjeooIeaosVFvE8cmYUB4TSH
|
||||||
|
5dUyD0jHct2+8ceKEtIoFU/FfHq/mDaVnvcDCZXtIgitdMFQdMZaVehmObyhRdDD
|
||||||
|
4NQCs0gaI9AAgFj4L9QtkARzhQLNyRf87Kln+YU0lgCGr9HLg3rGO8q+Y4ppLsOd
|
||||||
|
unQZ6ZxPNGIfOApbPVf5hCe58EZwiWdHIMn9lPP6+F404y8NNugbQixBber+x536
|
||||||
|
WrZhFZLjEkhp7fFXf9r32rNPfb74X/U90Bdy4lzp3+X1ukh1BuMxA/EEhDoTOS3l
|
||||||
|
7ABvc7BYSQubQ2490OcdkIzUh3ZwDrakMVrbaTxUM2p24N6dB+ns2zptWCva6jzW
|
||||||
|
r8IWKIMxzxLPv5Kt3ePKcUdvkBU/smqujSczTzzSjIoR5QqQA6lN1ZRSnuHIWCvh
|
||||||
|
JEltkYnTAH41QJ6SAWO66GrrUESwN/cgZzL4JLEqz1Y=
|
||||||
|
-----END CERTIFICATE-----`
|
||||||
|
|
||||||
|
const sectigoOld string = `-----BEGIN CERTIFICATE-----
|
||||||
|
MIIGEzCCA/ugAwIBAgIQfVtRJrR2uhHbdBYLvFMNpzANBgkqhkiG9w0BAQwFADCB
|
||||||
|
iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl
|
||||||
|
cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV
|
||||||
|
BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTgx
|
||||||
|
MTAyMDAwMDAwWhcNMzAxMjMxMjM1OTU5WjCBjzELMAkGA1UEBhMCR0IxGzAZBgNV
|
||||||
|
BAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEYMBYGA1UE
|
||||||
|
ChMPU2VjdGlnbyBMaW1pdGVkMTcwNQYDVQQDEy5TZWN0aWdvIFJTQSBEb21haW4g
|
||||||
|
VmFsaWRhdGlvbiBTZWN1cmUgU2VydmVyIENBMIIBIjANBgkqhkiG9w0BAQEFAAOC
|
||||||
|
AQ8AMIIBCgKCAQEA1nMz1tc8INAA0hdFuNY+B6I/x0HuMjDJsGz99J/LEpgPLT+N
|
||||||
|
TQEMgg8Xf2Iu6bhIefsWg06t1zIlk7cHv7lQP6lMw0Aq6Tn/2YHKHxYyQdqAJrkj
|
||||||
|
eocgHuP/IJo8lURvh3UGkEC0MpMWCRAIIz7S3YcPb11RFGoKacVPAXJpz9OTTG0E
|
||||||
|
oKMbgn6xmrntxZ7FN3ifmgg0+1YuWMQJDgZkW7w33PGfKGioVrCSo1yfu4iYCBsk
|
||||||
|
Haswha6vsC6eep3BwEIc4gLw6uBK0u+QDrTBQBbwb4VCSmT3pDCg/r8uoydajotY
|
||||||
|
uK3DGReEY+1vVv2Dy2A0xHS+5p3b4eTlygxfFQIDAQABo4IBbjCCAWowHwYDVR0j
|
||||||
|
BBgwFoAUU3m/WqorSs9UgOHYm8Cd8rIDZsswHQYDVR0OBBYEFI2MXsRUrYrhd+mb
|
||||||
|
+ZsF4bgBjWHhMA4GA1UdDwEB/wQEAwIBhjASBgNVHRMBAf8ECDAGAQH/AgEAMB0G
|
||||||
|
A1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAbBgNVHSAEFDASMAYGBFUdIAAw
|
||||||
|
CAYGZ4EMAQIBMFAGA1UdHwRJMEcwRaBDoEGGP2h0dHA6Ly9jcmwudXNlcnRydXN0
|
||||||
|
LmNvbS9VU0VSVHJ1c3RSU0FDZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDB2Bggr
|
||||||
|
BgEFBQcBAQRqMGgwPwYIKwYBBQUHMAKGM2h0dHA6Ly9jcnQudXNlcnRydXN0LmNv
|
||||||
|
bS9VU0VSVHJ1c3RSU0FBZGRUcnVzdENBLmNydDAlBggrBgEFBQcwAYYZaHR0cDov
|
||||||
|
L29jc3AudXNlcnRydXN0LmNvbTANBgkqhkiG9w0BAQwFAAOCAgEAMr9hvQ5Iw0/H
|
||||||
|
ukdN+Jx4GQHcEx2Ab/zDcLRSmjEzmldS+zGea6TvVKqJjUAXaPgREHzSyrHxVYbH
|
||||||
|
7rM2kYb2OVG/Rr8PoLq0935JxCo2F57kaDl6r5ROVm+yezu/Coa9zcV3HAO4OLGi
|
||||||
|
H19+24rcRki2aArPsrW04jTkZ6k4Zgle0rj8nSg6F0AnwnJOKf0hPHzPE/uWLMUx
|
||||||
|
RP0T7dWbqWlod3zu4f+k+TY4CFM5ooQ0nBnzvg6s1SQ36yOoeNDT5++SR2RiOSLv
|
||||||
|
xvcRviKFxmZEJCaOEDKNyJOuB56DPi/Z+fVGjmO+wea03KbNIaiGCpXZLoUmGv38
|
||||||
|
sbZXQm2V0TP2ORQGgkE49Y9Y3IBbpNV9lXj9p5v//cWoaasm56ekBYdbqbe4oyAL
|
||||||
|
l6lFhd2zi+WJN44pDfwGF/Y4QA5C5BIG+3vzxhFoYt/jmPQT2BVPi7Fp2RBgvGQq
|
||||||
|
6jG35LWjOhSbJuMLe/0CjraZwTiXWTb2qHSihrZe68Zk6s+go/lunrotEbaGmAhY
|
||||||
|
LcmsJWTyXnW0OMGuf1pGg+pRyrbxmRE1a6Vqe8YAsOf4vmSyrcjC8azjUeqkk+B5
|
||||||
|
yOGBQMkKW+ESPMFgKuOXwIlCypTPRpgSabuY0MLTDXJLR27lk8QyKGOHQ+SwMj4K
|
||||||
|
00u/I5sUKUErmgQfky3xxzlIPK1aEn8=
|
||||||
|
-----END CERTIFICATE-----`
|
||||||
Reference in New Issue
Block a user