mirror of
https://github.com/Control-D-Inc/ctrld.git
synced 2026-10-24 14:08:27 +02:00
certs: block compromised eMudhra intermediates (CVE-2026-111943)
This commit is contained in:
1 parent
4b665dd504
commit
5a9ddba7ac
8 files changed
+1064
-1127
No files matched your search
+1
-1
@@ -12,7 +12,7 @@
|
||||
# ctrld for the target platform, so no build step runs under qemu emulation.
|
||||
# buildx sets BUILDPLATFORM and the TARGET* arguments from --platform, e.g.
|
||||
# linux/arm/v7 gives TARGETOS=linux, TARGETARCH=arm, TARGETVARIANT=v7.
|
||||
FROM --platform=$BUILDPLATFORM golang:1.27-bookworm AS base
|
||||
FROM --platform=$BUILDPLATFORM golang:1.27.3-bookworm AS base
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
# ctrld for the target platform, so no build step runs under qemu emulation.
|
||||
# buildx sets BUILDPLATFORM and the TARGET* arguments from --platform, e.g.
|
||||
# linux/arm/v7 gives TARGETOS=linux, TARGETARCH=arm, TARGETVARIANT=v7.
|
||||
FROM --platform=$BUILDPLATFORM golang:1.27-bookworm AS base
|
||||
FROM --platform=$BUILDPLATFORM golang:1.27.3-bookworm AS base
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@ module github.com/Control-D-Inc/ctrld
|
||||
|
||||
go 1.26.0
|
||||
|
||||
toolchain go1.26.10
|
||||
|
||||
require (
|
||||
github.com/Masterminds/semver/v3 v3.2.1
|
||||
github.com/ameshkov/dnsstamps v1.0.3
|
||||
|
||||
+769
-1125
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,150 @@
|
||||
package certs
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/x509"
|
||||
"embed"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
// The fixtures are embedded rather than read from disk: test:windows runs
|
||||
// cross-compiled test binaries with no source checkout (GIT_STRATEGY: none).
|
||||
//
|
||||
//go:embed testdata/*.pem
|
||||
var testdata embed.FS
|
||||
|
||||
// Chains served by the eMudhra disclosure test hosts
|
||||
// (https://emudhra.we-have-a-problem.com/chains.zip, captured 2026-10-20).
|
||||
// Each file is leaf first, then the intermediates the host sends. The
|
||||
// intermediate keys are publicly recoverable (CVE-2026-111943), so none of
|
||||
// these chains may verify.
|
||||
var emudhraChains = []string{
|
||||
// EM DV TLS CA - G3B -> emSign Root TLS CA - G3 -> emSign ECC Root CA - G3
|
||||
"dv-g3b-emudhra.we-have-a-problem.com.pem",
|
||||
// EM DV TLS CA - G3B cross-signed by AAA Certificate Services
|
||||
"dv-g3b-aaa-emudhra.we-have-a-problem.com.pem",
|
||||
}
|
||||
|
||||
// verifyAt is inside every certificate's validity window, so a rejection
|
||||
// below comes from trust, not from expiry.
|
||||
var verifyAt = time.Date(2026, time.October, 21, 0, 0, 0, 0, time.UTC)
|
||||
|
||||
func readCerts(t *testing.T, name string) []*x509.Certificate {
|
||||
t.Helper()
|
||||
b, err := testdata.ReadFile("testdata/" + name)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return parsePEMCerts(t, name, b)
|
||||
}
|
||||
|
||||
func parsePEMCerts(t *testing.T, name string, b []byte) []*x509.Certificate {
|
||||
t.Helper()
|
||||
var certs []*x509.Certificate
|
||||
for {
|
||||
var block *pem.Block
|
||||
block, b = pem.Decode(b)
|
||||
if block == nil {
|
||||
break
|
||||
}
|
||||
if block.Type != "CERTIFICATE" {
|
||||
continue
|
||||
}
|
||||
c, err := x509.ParseCertificate(block.Bytes)
|
||||
if err != nil {
|
||||
t.Fatalf("%s: %v", name, err)
|
||||
}
|
||||
certs = append(certs, c)
|
||||
}
|
||||
if len(certs) == 0 {
|
||||
t.Fatalf("%s: no certificates", name)
|
||||
}
|
||||
return certs
|
||||
}
|
||||
|
||||
func verifyChain(t *testing.T, name string, roots *x509.CertPool) error {
|
||||
t.Helper()
|
||||
chain := readCerts(t, name)
|
||||
inter := x509.NewCertPool()
|
||||
for _, c := range chain[1:] {
|
||||
inter.AddCert(c)
|
||||
}
|
||||
_, err := chain[0].Verify(x509.VerifyOptions{
|
||||
DNSName: chain[0].Subject.CommonName,
|
||||
Roots: roots,
|
||||
Intermediates: inter,
|
||||
CurrentTime: verifyAt,
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
// requireTrustRejection fails unless err is a trust rejection. Any other
|
||||
// verification error (hostname mismatch, expiry after verifyAt drifts, a
|
||||
// broken fixture) would let the chain checks pass without proving anything.
|
||||
func requireTrustRejection(t *testing.T, name string, err error) {
|
||||
t.Helper()
|
||||
if err == nil {
|
||||
return
|
||||
}
|
||||
t.Logf("%s: %v", name, err)
|
||||
var hostErr x509.HostnameError
|
||||
if errors.As(err, &hostErr) {
|
||||
t.Errorf("%s: rejected for hostname, not trust: %v", name, err)
|
||||
}
|
||||
var invErr x509.CertificateInvalidError
|
||||
if errors.As(err, &invErr) && invErr.Reason == x509.Expired {
|
||||
t.Errorf("%s: rejected for expiry, not trust: %v", name, err)
|
||||
}
|
||||
}
|
||||
|
||||
// The embedded bundle is the only trust store on DD-WRT (upstream DoH/DoT/DoQ)
|
||||
// and on Android (Control D API), so it must not contain the affected roots.
|
||||
// This checks the bundle contents directly: on a fixed toolchain the chain
|
||||
// verification below passes even with the affected roots present.
|
||||
func TestCACertBundleExcludesAffectedEMudhraRoots(t *testing.T) {
|
||||
bundle := parsePEMCerts(t, "cacert.pem", caRoots)
|
||||
for _, root := range readCerts(t, "emudhra-roots.pem") {
|
||||
for _, c := range bundle {
|
||||
// Raw catches the exact certificate; subject + key also catches a
|
||||
// re-issued form of the same root.
|
||||
if bytes.Equal(c.Raw, root.Raw) ||
|
||||
(bytes.Equal(c.RawSubject, root.RawSubject) &&
|
||||
bytes.Equal(c.RawSubjectPublicKeyInfo, root.RawSubjectPublicKeyInfo)) {
|
||||
t.Errorf("embedded cacert.pem contains affected root %q", root.Subject.CommonName)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCACertPoolRejectsCompromisedEMudhraChains(t *testing.T) {
|
||||
for _, name := range emudhraChains {
|
||||
err := verifyChain(t, name, CACertPool())
|
||||
if err == nil {
|
||||
t.Errorf("%s: embedded cacert.pem trusts a compromised eMudhra intermediate", name)
|
||||
continue
|
||||
}
|
||||
requireTrustRejection(t, name, err)
|
||||
}
|
||||
}
|
||||
|
||||
// Every other platform verifies against the OS store, which may still carry
|
||||
// the affected roots. Go 1.26.10 / 1.27.3 reject the compromised intermediates
|
||||
// inside crypto/x509 regardless of roots; this fails if the build toolchain
|
||||
// predates that fix.
|
||||
func TestToolchainRejectsCompromisedEMudhraIntermediates(t *testing.T) {
|
||||
roots := x509.NewCertPool()
|
||||
for _, c := range readCerts(t, "emudhra-roots.pem") {
|
||||
roots.AddCert(c)
|
||||
}
|
||||
for _, name := range emudhraChains {
|
||||
err := verifyChain(t, name, roots)
|
||||
if err == nil {
|
||||
t.Errorf("%s: crypto/x509 accepted a compromised eMudhra intermediate with its root trusted; build with go1.26.10+ or go1.27.3+", name)
|
||||
continue
|
||||
}
|
||||
requireTrustRejection(t, name, err)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICQDCCAcagAwIBAgIUU3mgjls/8ZJ8upmukdlSQR1IF/UwCgYIKoZIzj0EAwIw
|
||||
PzELMAkGA1UEBhMCTkwxEzARBgNVBAoMCmVNdWRocmEgQlYxGzAZBgNVBAMMEkVN
|
||||
IERWIFRMUyBDQSAtIEczQjAeFw0yNjEwMjAwMjIyNDFaFw0yNzA1MDMwMjI3NDFa
|
||||
MDMxMTAvBgNVBAMMKGR2LWczYi1hYWEtZW11ZGhyYS53ZS1oYXZlLWEtcHJvYmxl
|
||||
bS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATK3sfcOxxtM2Vdq9Qbw/GR
|
||||
NsHlJcnqINEInXO3fkWhw/FYT80hkqGk0jSN/EKib3YZJsr5GyfkYcpEiA2rwMgm
|
||||
o4GrMIGoMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoG
|
||||
CCsGAQUFBwMBMDMGA1UdEQQsMCqCKGR2LWczYi1hYWEtZW11ZGhyYS53ZS1oYXZl
|
||||
LWEtcHJvYmxlbS5jb20wHQYDVR0OBBYEFDggfJFz1eeToKmzFBSYkMCvpAu0MB8G
|
||||
A1UdIwQYMBaAFOIeL+ccGTkOVUtiwSAkVzUkiiUUMAoGCCqGSM49BAMCA2gAMGUC
|
||||
MDqDDOt7K313QIH0rhn/ZKnzFu8+/9W8OlTuFtDfVCTRDfRmqdyfsCfLsEk7xqHq
|
||||
uQIxAJqyLERABmU98U46OCuT5bp5h0ytuSEIGM7orTpKci5S1u1B/AOmwv162U7R
|
||||
TcVPHA==
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDzjCCAragAwIBAgIRAKAk/fS6Zlx4XOSgIEg4WLcwDQYJKoZIhvcNAQELBQAw
|
||||
ezELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
|
||||
A1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNV
|
||||
BAMMGEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczAeFw0yNTA1MTQwMDAwMDBaFw0y
|
||||
ODEyMzEyMzU5NTlaMD8xCzAJBgNVBAYTAk5MMRMwEQYDVQQKDAplTXVkaHJhIEJW
|
||||
MRswGQYDVQQDDBJFTSBEViBUTFMgQ0EgLSBHM0IwdjAQBgcqhkjOPQIBBgUrgQQA
|
||||
IgNiAATnntnASpdzxHNeUREdqFrCvV5kqzdLgOEsvCA47B5PDjuBL8mFnh5nr7BO
|
||||
L4vJf3SFumWqkR7opORbYtXMA9Vr5nizw4y03JN8okYOI4RTyJKTXSnUT5HhVga2
|
||||
PM7atGijggE1MIIBMTAfBgNVHSMEGDAWgBSgEQojPpbxB+zirynvgqV/0DCktDAd
|
||||
BgNVHQ4EFgQU4h4v5xwZOQ5VS2LBICRXNSSKJRQwDgYDVR0PAQH/BAQDAgEGMBIG
|
||||
A1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMC
|
||||
MDEGA1UdIAQqMCgwCAYGZ4EMAQIBMA0GCysGAQQBg44hAQABMA0GCysGAQQBg44h
|
||||
AQJkMEMGA1UdHwQ8MDowOKA2oDSGMmh0dHA6Ly9jcmwuY29tb2RvY2EuY29tL0FB
|
||||
QUNlcnRpZmljYXRlU2VydmljZXMuY3JsMDQGCCsGAQUFBwEBBCgwJjAkBggrBgEF
|
||||
BQcwAYYYaHR0cDovL29jc3AuY29tb2RvY2EuY29tMA0GCSqGSIb3DQEBCwUAA4IB
|
||||
AQBzQ1IoqpdotM6gFrR4Q3YrKifOLeaj5XXunldpVE/vZn2TxC2y0s8oYiLR5ICE
|
||||
wqVXSB7N6BM1Mp+Nif7Jbhb2IswAfSR4Iik8+B0iRmi7lYoNlycCgHjmsjOmZaxM
|
||||
QkPmjXAJbG5f4V41OsvJZmS7lI3r0IuvEDVX3GAZ13on6IImSs9ybNpHQ7NCqkMQ
|
||||
7wH4uAO1dtpFycgJSdHaCOhHjrox2BTYGLdpUrYwY3EOAjlZ8UGgsxs7mG+xquMl
|
||||
bN1LFURwfnkVMP3T/DBIZ/ys2+lNFyxK3FlArrV4/000uTnVB1lO8oGORYdXoT5V
|
||||
GUyRCEIDhF5TBUuKF4E3kf1h
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,56 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICOTCCAb6gAwIBAgIUY1R/PHrtXShV0uhLJ5EyjsHvMi0wCgYIKoZIzj0EAwIw
|
||||
PzELMAkGA1UEBhMCTkwxEzARBgNVBAoMCmVNdWRocmEgQlYxGzAZBgNVBAMMEkVN
|
||||
IERWIFRMUyBDQSAtIEczQjAeFw0yNjEwMjAwMDU5MzZaFw0yNzA1MDMwMTA0MzZa
|
||||
MC8xLTArBgNVBAMMJGR2LWczYi1lbXVkaHJhLndlLWhhdmUtYS1wcm9ibGVtLmNv
|
||||
bTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABFpE24ACBFHQLzpg+7D767thJ3+Q
|
||||
NIoJJugUMT/OftEz6G6uDdxlS+9VfXYBDglHjJirjEPFNglOGJoQNQuiz7Gjgacw
|
||||
gaQwDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYIKwYB
|
||||
BQUHAwEwLwYDVR0RBCgwJoIkZHYtZzNiLWVtdWRocmEud2UtaGF2ZS1hLXByb2Js
|
||||
ZW0uY29tMB0GA1UdDgQWBBT4r5v4etYNuG21BqBqs273OkcHiDAfBgNVHSMEGDAW
|
||||
gBTiHi/nHBk5DlVLYsEgJFc1JIolFDAKBggqhkjOPQQDAgNpADBmAjEAlxNF+/8l
|
||||
APpgibawACy15yn5bcvTksz2Zw0R9z9nUK9e3MSSk+hXagg7LVb7V4NtAjEA4qyR
|
||||
laFPkaokrnTjqQieq8CgDQ6tIz3FjBvj3D7vkhKXHaml6zD2zT5ih2Y+lD2h
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDaDCCAu6gAwIBAgIQAKSu5njyM2K0wORgt3LyFDAKBggqhkjOPQQDAzBWMQsw
|
||||
CQYDVQQGEwJJTjElMCMGA1UECgwcZU11ZGhyYSBUZWNobm9sb2dpZXMgTGltaXRl
|
||||
ZDEgMB4GA1UEAwwXZW1TaWduIFJvb3QgVExTIENBIC0gRzMwHhcNMjUwNDMwMTU1
|
||||
NDA4WhcNNDAwNDI4MTgzMDAwWjA/MQswCQYDVQQGEwJOTDETMBEGA1UECgwKZU11
|
||||
ZGhyYSBCVjEbMBkGA1UEAwwSRU0gRFYgVExTIENBIC0gRzNCMHYwEAYHKoZIzj0C
|
||||
AQYFK4EEACIDYgAE557ZwEqXc8RzXlERHahawr1eZKs3S4DhLLwgOOweTw47gS/J
|
||||
hZ4eZ6+wTi+LyX90hbplqpEe6KTkW2LVzAPVa+Z4s8OMtNyTfKJGDiOEU8iSk10p
|
||||
1E+R4VYGtjzO2rRoo4IBljCCAZIwHwYDVR0jBBgwFoAU4TqrIXzx401UrtRyt/2L
|
||||
WUIgkFQwHQYDVR0OBBYEFOIeL+ccGTkOVUtiwSAkVzUkiiUUMB0GA1UdJQQWMBQG
|
||||
CCsGAQUFBwMBBggrBgEFBQcDAjBdBgNVHSAEVjBUMDkGCysGAQQBg44hAQABMCow
|
||||
KAYIKwYBBQUHAgEWHGh0dHA6Ly9yZXBvc2l0b3J5LmVtc2lnbi5jb20wDQYLKwYB
|
||||
BAGDjiEBAmQwCAYGZ4EMAQIBMHUGCCsGAQUFBwEBBGkwZzAkBggrBgEFBQcwAYYY
|
||||
aHR0cDovL29jc3AtYi5lbXNpZ24uY29tMD8GCCsGAQUFBzAChjNodHRwOi8vcmVw
|
||||
b3NpdG9yeS5lbXNpZ24uY29tL2NlcnRzL0VNRFZUTFNDQUczQi5wN2MwNwYDVR0f
|
||||
BDAwLjAsoCqgKIYmaHR0cDovL2NybC5lbXNpZ24uY29tLz9yb290dGxzY2FnMy5j
|
||||
cmwwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQAwCgYIKoZIzj0E
|
||||
AwMDaAAwZQIwLmsGXi6oFMJ2klkcEMXMug6gvxQWZWkewiDWVzQyl2L6z6DuQfPO
|
||||
Ibh1grvdULDCAjEAxZvLlxUavG69J6wnSjC8XBbqNIQsJ6CE2QdNOe84Ptxb6VG8
|
||||
gt2TlfJbHii+KNvK
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDdDCCAvmgAwIBAgIQAJYaPvsTWVdu0EAFtGhKWzAKBggqhkjOPQQDAzBrMQsw
|
||||
CQYDVQQGEwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhy
|
||||
YSBUZWNobm9sb2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290
|
||||
IENBIC0gRzMwHhcNMjQwNzExMTU0MzM2WhcNMzkwNzA5MTgzMDAwWjBWMQswCQYD
|
||||
VQQGEwJJTjElMCMGA1UECgwcZU11ZGhyYSBUZWNobm9sb2dpZXMgTGltaXRlZDEg
|
||||
MB4GA1UEAwwXZW1TaWduIFJvb3QgVExTIENBIC0gRzMwdjAQBgcqhkjOPQIBBgUr
|
||||
gQQAIgNiAARfD9w/q1cWxL6D9bMGH6CQ4u+gAV6GN9s+PwQx9Bl4hC+0iU8QOk8m
|
||||
WO/RwXQy10DCSxT8vSIJClHKp+Ao4qJKdYeV0SwZ7LMQziyLfxIUOY6Grja/sQFw
|
||||
LKYf8EdDXAyjggF1MIIBcTAfBgNVHSMEGDAWgBR8XQKEE9TMipuBzhccLikenEhj
|
||||
QjAdBgNVHQ4EFgQU4TqrIXzx401UrtRyt/2LWUIgkFQwHQYDVR0lBBYwFAYIKwYB
|
||||
BQUHAwEGCCsGAQUFBwMCMD0GA1UdIAQ2MDQwMgYEVR0gADAqMCgGCCsGAQUFBwIB
|
||||
FhxodHRwOi8vcmVwb3NpdG9yeS5lbXNpZ24uY29tMHgGCCsGAQUFBwEBBGwwajAi
|
||||
BggrBgEFBQcwAYYWaHR0cDovL29jc3AuZW1zaWduLmNvbTBEBggrBgEFBQcwAoY4
|
||||
aHR0cDovL3JlcG9zaXRvcnkuZW1zaWduLmNvbS9jZXJ0cy9lbVNpZ25FQ0NSb290
|
||||
Q0FHMy5jcnQwMwYDVR0fBCwwKjAooCagJIYiaHR0cDovL2NybC5lbXNpZ24uY29t
|
||||
P1Jvb3RDQUczLmNybDAOBgNVHQ8BAf8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIB
|
||||
ATAKBggqhkjOPQQDAwNpADBmAjEAt9CIpRGp46QHQYDUBnLKw+vvK0/h9vmilEAg
|
||||
TroUl/anH4x2rXHqiCtBTBfgKDegAjEA8WpG1LTZdAIL0FSYqxXeREaeTSxEofM0
|
||||
1jJH3jGvCXC79LU9UPJ2o3TU+UIj2gMV
|
||||
-----END CERTIFICATE-----
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
# Roots the compromised eMudhra intermediates chain to, from
|
||||
# https://emudhra.we-have-a-problem.com/roots.json (captured 2026-10-21).
|
||||
# Used only by tests, never as a trust store.
|
||||
|
||||
# emSign ECC Root CA - G3
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICTjCCAdOgAwIBAgIKPPYHqWhwDtqLhDAKBggqhkjOPQQDAzBrMQswCQYDVQQG
|
||||
EwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNo
|
||||
bm9sb2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0g
|
||||
RzMwHhcNMTgwMjE4MTgzMDAwWhcNNDMwMjE4MTgzMDAwWjBrMQswCQYDVQQGEwJJ
|
||||
TjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNobm9s
|
||||
b2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0gRzMw
|
||||
djAQBgcqhkjOPQIBBgUrgQQAIgNiAAQjpQy4LRL1KPOxst3iAhKAnjlfSU2fySU0
|
||||
WXTsuwYc58Byr+iuL+FBVIcUqEqy6HyC5ltqtdyzdc6LBtCGI79G1Y4PPwT01xyS
|
||||
fvalY8L1X44uT6EYGQIrMgqCZH0Wk9GjQjBAMB0GA1UdDgQWBBR8XQKEE9TMipuB
|
||||
zhccLikenEhjQjAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggq
|
||||
hkjOPQQDAwNpADBmAjEAvvNhzwIQHWSVB7gYboiFBS+DCBeQyh+KTOgNG3qxrdWB
|
||||
CUfvO6wIBHxcmbHtRwfSAjEAnbpV/KlK6O3t5nYBQnvI+GDZjVGLVTv7jHvrZQnD
|
||||
+JbNR6iC8hZVdyR+EhCVBCyj
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
# AAA Certificate Services
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb
|
||||
MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow
|
||||
GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj
|
||||
YXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL
|
||||
MAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE
|
||||
BwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM
|
||||
GEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP
|
||||
ADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua
|
||||
BtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe
|
||||
3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4
|
||||
YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR
|
||||
rOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm
|
||||
ez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU
|
||||
oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF
|
||||
MAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v
|
||||
QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t
|
||||
b2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF
|
||||
AAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q
|
||||
GE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz
|
||||
Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2
|
||||
G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi
|
||||
l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3
|
||||
smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg==
|
||||
-----END CERTIFICATE-----
|
||||
Reference in new issue
Block a user