Add OCSP support

Signed-off-by: Waldemar Quevedo <wally@synadia.com>
This commit is contained in:
Jaime Piña
2021-05-06 00:32:54 -07:00
committed by Waldemar Quevedo
parent 0072107110
commit b2e1ff7a7c
17 changed files with 2116 additions and 1 deletions

454
server/ocsp.go Normal file
View File

@@ -0,0 +1,454 @@
// Copyright 2021 The NATS Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package server
import (
"crypto/tls"
"crypto/x509"
"encoding/asn1"
"encoding/base64"
"encoding/pem"
"fmt"
"io/ioutil"
"net/http"
"strings"
"sync"
"time"
"golang.org/x/crypto/ocsp"
)
const (
defaultOCSPCheckInterval = 24 * time.Hour
minOCSPCheckInterval = 2 * time.Minute
)
type OCSPMode uint8
const (
// OCSPModeAuto staples a status, only if "status_request" is set in cert.
OCSPModeAuto OCSPMode = iota
// OCSPModeAlways enforces OCSP stapling for certs and shuts down the server in
// case a server is revoked or cannot get OCSP staples.
OCSPModeAlways
// OCSPModeNever disables OCSP stapling even if cert has Must-Staple flag.
OCSPModeNever
// OCSPModeMust honors the Must-Staple flag from a certificate but also causing shutdown
// in case the certificate has been revoked.
OCSPModeMust
)
// OCSPMonitor monitors the state of a staple per certificate.
type OCSPMonitor struct {
mu sync.Mutex
raw []byte
srv *Server
certFile string
resp *ocsp.Response
hc *http.Client
stopCh chan struct{}
Leaf *x509.Certificate
Issuer *x509.Certificate
shutdownOnRevoke bool
}
func (oc *OCSPMonitor) getNextRun() time.Duration {
oc.mu.Lock()
nextUpdate := oc.resp.NextUpdate
oc.mu.Unlock()
now := time.Now()
if nextUpdate.IsZero() {
// If response is missing NextUpdate, we check the day after.
// Technically, if NextUpdate is missing, we can try whenever.
// https://tools.ietf.org/html/rfc6960#section-4.2.2.1
return defaultOCSPCheckInterval
}
dur := nextUpdate.Sub(now) / 2
// If negative, then wait a couple of minutes before getting another staple.
if dur < 0 {
return minOCSPCheckInterval
}
return dur
}
func (oc *OCSPMonitor) getStatus() ([]byte, *ocsp.Response, error) {
raw, resp := oc.getCacheStatus()
if len(raw) > 0 && resp != nil {
return raw, resp, nil
}
return oc.getRemoteStatus()
}
func (oc *OCSPMonitor) getCacheStatus() ([]byte, *ocsp.Response) {
oc.mu.Lock()
defer oc.mu.Unlock()
return oc.raw, oc.resp
}
func (oc *OCSPMonitor) getRemoteStatus() ([]byte, *ocsp.Response, error) {
opts := oc.srv.getOpts()
var overrideURLs []string
if config := opts.OCSPConfig; config != nil {
overrideURLs = config.OverrideURLs
}
getRequestBytes := func(u string, hc *http.Client) ([]byte, error) {
resp, err := hc.Get(u)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("non-ok http status: %d", resp.StatusCode)
}
return ioutil.ReadAll(resp.Body)
}
// Request documentation:
// https://tools.ietf.org/html/rfc6960#appendix-A.1
reqDER, err := ocsp.CreateRequest(oc.Leaf, oc.Issuer, nil)
if err != nil {
return nil, nil, err
}
reqEnc := base64.StdEncoding.EncodeToString(reqDER)
responders := oc.Leaf.OCSPServer
if len(overrideURLs) > 0 {
responders = overrideURLs
}
if len(responders) == 0 {
return nil, nil, fmt.Errorf("no available ocsp servers")
}
oc.mu.Lock()
hc := oc.hc
oc.mu.Unlock()
var raw []byte
for _, u := range responders {
u = strings.TrimSuffix(u, "/")
raw, err = getRequestBytes(fmt.Sprintf("%s/%s", u, reqEnc), hc)
if err == nil {
break
}
}
if err != nil {
return nil, nil, fmt.Errorf("exhausted ocsp servers: %w", err)
}
resp, err := ocsp.ParseResponse(raw, oc.Issuer)
if err != nil {
return nil, nil, err
}
if err := validOCSPResponse(resp); err != nil {
return nil, nil, err
}
oc.mu.Lock()
oc.raw = raw
oc.resp = resp
oc.mu.Unlock()
return raw, resp, nil
}
func (oc *OCSPMonitor) run() {
s := oc.srv
s.mu.Lock()
quitCh := s.quitCh
s.mu.Unlock()
defer s.grWG.Done()
oc.mu.Lock()
shutdownOnRevoke := oc.shutdownOnRevoke
certFile := oc.certFile
stopCh := oc.stopCh
oc.mu.Unlock()
var nextRun time.Duration
_, resp, err := oc.getStatus()
if err == nil && resp.Status == ocsp.Good {
nextRun = oc.getNextRun()
t := resp.NextUpdate.Format(time.RFC3339Nano)
s.Noticef(
"Found existing OCSP status for certificate at '%s': good, next update %s, checking again in %s",
certFile, t, nextRun,
)
} else if err == nil && shutdownOnRevoke {
// If resp.Status is ocsp.Revoked, ocsp.Unknown, or any other value.
s.Errorf("Found existing OCSP status for certificate at '%s': %s", certFile, ocspStatusString(resp.Status))
s.Shutdown()
return
}
for s.Running() {
// On reload, if the certificate changes then need to stop this monitor.
select {
case <-time.After(nextRun):
case <-stopCh:
// In case of reload and have to restart the OCSP stapling monitoring.
return
case <-quitCh:
// Server quit channel.
return
}
_, resp, err := oc.getRemoteStatus()
if err != nil {
nextRun = oc.getNextRun()
s.Errorf("Bad OCSP status update for certificate '%s': %s, trying again in %v", certFile, err, nextRun)
continue
}
switch n := resp.Status; n {
case ocsp.Good:
nextRun = oc.getNextRun()
t := resp.NextUpdate.Format(time.RFC3339Nano)
s.Noticef(
"Received OCSP status for certificate '%s': good, next update %s, checking again in %s",
certFile, t, nextRun,
)
continue
default:
s.Errorf("Received OCSP certificate status: %s", ocspStatusString(n))
if shutdownOnRevoke {
s.Shutdown()
}
return
}
}
}
func (oc *OCSPMonitor) stop() {
oc.mu.Lock()
stopCh := oc.stopCh
oc.mu.Unlock()
stopCh <- struct{}{}
}
// NewOCSPMonitor takes a TLS configuration then wraps it with the callbacks set for OCSP verification
// along with a monitor that will periodically fetch OCSP staples.
func (srv *Server) NewOCSPMonitor(tc *tls.Config) (*tls.Config, *OCSPMonitor, error) {
opts := srv.getOpts()
oc := opts.OCSPConfig
tcOpts := opts.tlsConfigOpts
var certFile, caFile string
if tcOpts != nil {
certFile = tcOpts.CertFile
caFile = tcOpts.CaFile
}
if opts.TLSCert != _EMPTY_ {
certFile = opts.TLSCert
}
if opts.TLSCaCert != _EMPTY_ {
caFile = opts.TLSCaCert
}
// NOTE: Currently OCSP Stapling is enabled only for the first certificate found.
var mon *OCSPMonitor
for _, cert := range tc.Certificates {
var shutdownOnRevoke bool
mustStaple := hasOCSPStatusRequest(cert.Leaf)
if oc != nil {
switch {
case oc.Mode == OCSPModeNever:
if mustStaple {
srv.Warnf("Certificate at '%s' has MustStaple but OCSP is disabled", certFile)
}
return tc, nil, nil
case oc.Mode == OCSPModeAlways:
// Start the monitor for this cert even if it does not have
// the MustStaple flag and shutdown the server in case the
// staple ever gets revoked.
mustStaple = true
shutdownOnRevoke = true
case oc.Mode == OCSPModeMust && mustStaple:
shutdownOnRevoke = true
case oc.Mode == OCSPModeAuto && !mustStaple:
// "status_request" MustStaple flag not set in certificate. No need to do anything.
return tc, nil, nil
}
}
if !mustStaple {
// No explicit OCSP config and cert does not have MustStaple flag either.
return tc, nil, nil
}
// TODO: Add OCSP 'responder_cert' option in case CA cert not available.
issuer, err := getOCSPIssuer(caFile, cert.Certificate)
if err != nil {
return nil, nil, err
}
mon = &OCSPMonitor{
srv: srv,
hc: &http.Client{Timeout: 30 * time.Second},
shutdownOnRevoke: shutdownOnRevoke,
certFile: certFile,
stopCh: make(chan struct{}, 1),
Leaf: cert.Leaf,
Issuer: issuer,
}
// Get the certificate status from the memory, then remote OCSP responder.
_, resp, err := mon.getStatus()
if err != nil {
return nil, nil, fmt.Errorf("bad OCSP status update for certificate at '%s': %s", certFile, err)
}
if err == nil && resp.Status != ocsp.Good && shutdownOnRevoke {
return nil, nil, fmt.Errorf("found existing OCSP status for certificate at '%s': %s", certFile, ocspStatusString(resp.Status))
}
// Callbacks below will be in charge of returning the certificate instead,
// so this has to be nil.
tc.Certificates = nil
// GetCertificate returns a certificate that's presented to a
// client.
tc.GetCertificate = func(info *tls.ClientHelloInfo) (*tls.Certificate, error) {
raw, _, err := mon.getStatus()
if err != nil {
return nil, err
}
return &tls.Certificate{
OCSPStaple: raw,
Certificate: cert.Certificate,
PrivateKey: cert.PrivateKey,
SupportedSignatureAlgorithms: cert.SupportedSignatureAlgorithms,
SignedCertificateTimestamps: cert.SignedCertificateTimestamps,
Leaf: cert.Leaf,
}, nil
}
// GetClientCertificate returns a certificate that's presented to a
// server.
tc.GetClientCertificate = func(info *tls.CertificateRequestInfo) (*tls.Certificate, error) {
return &cert, nil
}
}
return tc, mon, nil
}
func hasOCSPStatusRequest(cert *x509.Certificate) bool {
// OID for id-pe-tlsfeature defined in RFC here:
// https://datatracker.ietf.org/doc/html/rfc7633
tlsFeatures := asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 24}
const statusRequestExt = 5
// Example values:
// * [48 3 2 1 5] - seen when creating own certs locally
// * [30 3 2 1 5] - seen in the wild
// Documentation:
// https://tools.ietf.org/html/rfc6066
for _, ext := range cert.Extensions {
if !ext.Id.Equal(tlsFeatures) {
continue
}
var val []int
rest, err := asn1.Unmarshal(ext.Value, &val)
if err != nil || len(rest) > 0 {
return false
}
for _, n := range val {
if n == statusRequestExt {
return true
}
}
break
}
return false
}
func parseCertPEM(name string) (*x509.Certificate, error) {
data, err := ioutil.ReadFile(name)
if err != nil {
return nil, err
}
// Ignoring left over byte slice.
block, _ := pem.Decode(data)
if block == nil {
return nil, fmt.Errorf("failed to parse PEM cert %s", name)
}
if block.Type != "CERTIFICATE" {
return nil, fmt.Errorf("unexpected PEM certificate type: %s", block.Type)
}
return x509.ParseCertificate(block.Bytes)
}
// getOCSPIssuer returns a CA cert from the given path. If the path is empty,
// then this checks a given cert chain. If both are empty, then it returns an
// error.
func getOCSPIssuer(issuerCert string, chain [][]byte) (*x509.Certificate, error) {
var issuer *x509.Certificate
var err error
switch {
case len(chain) == 1 && issuerCert == _EMPTY_:
err = fmt.Errorf("require ocsp ca in chain or configuration")
case issuerCert != _EMPTY_:
issuer, err = parseCertPEM(issuerCert)
case len(chain) > 1 && issuerCert == _EMPTY_:
issuer, err = x509.ParseCertificate(chain[1])
default:
err = fmt.Errorf("invalid ocsp ca configuration")
}
if err != nil {
return nil, err
} else if !issuer.IsCA {
return nil, fmt.Errorf("%s invalid ca basic constraints: is not ca", issuerCert)
}
return issuer, nil
}
func ocspStatusString(n int) string {
switch n {
case ocsp.Good:
return "good"
case ocsp.Revoked:
return "revoked"
default:
return "unknown"
}
}
func validOCSPResponse(r *ocsp.Response) error {
// Time validation not handled by ParseResponse.
// https://tools.ietf.org/html/rfc6960#section-4.2.2.1
if !r.NextUpdate.IsZero() && r.NextUpdate.Before(time.Now()) {
t := r.NextUpdate.Format(time.RFC3339Nano)
return fmt.Errorf("invalid ocsp NextUpdate, is past time: %s", t)
}
if r.ThisUpdate.After(time.Now()) {
t := r.ThisUpdate.Format(time.RFC3339Nano)
return fmt.Errorf("invalid ocsp ThisUpdate, is future time: %s", t)
}
return nil
}

View File

@@ -268,6 +268,10 @@ type Options struct {
// and used as a filter criteria for some system requests
Tags jwt.TagList `json:"-"`
// OCSPConfig enables OCSP Stapling in the server.
OCSPConfig *OCSPConfig
tlsConfigOpts *TLSConfigOpts
// private fields, used to know if bool options are explicitly
// defined in config and/or command line params.
inConfig map[string]bool
@@ -485,6 +489,15 @@ type TLSConfigOpts struct {
PinnedCerts PinnedCertSet
}
// OCSPConfig represents the options of OCSP stapling options.
type OCSPConfig struct {
// Mode defines the policy for OCSP stapling.
Mode OCSPMode
// OverrideURLs is the http URL endpoint used to get OCSP staples.
OverrideURLs []string
}
var tlsUsage = `
TLS configuration is specified in the tls section of a configuration file:
@@ -841,6 +854,21 @@ func (o *Options) processConfigFileLine(k string, v interface{}, errors *[]error
o.TLSTimeout = tc.Timeout
o.TLSMap = tc.Map
o.TLSPinnedCerts = tc.PinnedCerts
// Need to keep track of path of the original TLS config
// and certs path for OCSP Stapling monitoring.
o.tlsConfigOpts = tc
case "ocsp":
switch v.(type) {
case bool:
// Default is Auto which honors Must Staple status request
// but does not shutdown the server in case it is revoked,
// letting the client choose whether to trust or not the server.
o.OCSPConfig = &OCSPConfig{Mode: OCSPModeAuto}
default:
*errors = append(*errors, &configErr{tk, fmt.Sprintf("error parsing ocsp config: unsupported type %T", v)})
return
}
case "allow_non_tls":
o.AllowNonTLS = v.(bool)
case "write_deadline":

View File

@@ -149,6 +149,7 @@ func TestTLSConfigFile(t *testing.T) {
t.Fatal("Expected opts.TLSConfig to be non-nil")
}
opts.TLSConfig = nil
opts.tlsConfigOpts = nil
checkOptionsEqual(t, golden, opts)
// Now check TLSConfig a bit more closely

View File

@@ -50,6 +50,9 @@ type option interface {
// IsAuthChange indicates if this option requires reloading authorization.
IsAuthChange() bool
// IsTLSChange indicates if this option requires reloading TLS.
IsTLSChange() bool
// IsClusterPermsChange indicates if this option requires reloading
// cluster permissions.
IsClusterPermsChange() bool
@@ -74,6 +77,10 @@ func (n noopOption) IsAuthChange() bool {
return false
}
func (n noopOption) IsTLSChange() bool {
return false
}
func (n noopOption) IsClusterPermsChange() bool {
return false
}
@@ -202,6 +209,10 @@ func (t *tlsOption) Apply(server *Server) {
server.Noticef("Reloaded: tls = %s", message)
}
func (t *tlsOption) IsTLSChange() bool {
return true
}
// tlsTimeoutOption implements the option interface for the tls `timeout`
// setting.
type tlsTimeoutOption struct {
@@ -802,7 +813,8 @@ func imposeOrder(value interface{}) error {
case WebsocketOpts:
sort.Strings(value.AllowedOrigins)
case string, bool, int, int32, int64, time.Duration, float64, nil, LeafNodeOpts, ClusterOpts, *tls.Config, PinnedCertSet,
*URLAccResolver, *MemAccResolver, *DirAccResolver, *CacheDirAccResolver, Authentication, MQTTOpts, jwt.TagList:
*URLAccResolver, *MemAccResolver, *DirAccResolver, *CacheDirAccResolver, Authentication, MQTTOpts, jwt.TagList,
*OCSPConfig:
// explicitly skipped types
default:
// this will fail during unit tests
@@ -1201,6 +1213,7 @@ func (s *Server) applyOptions(ctx *reloadContext, opts []option) {
reloadClientTrcLvl = false
reloadJetstream = false
jsEnabled = false
reloadTLS = false
)
for _, opt := range opts {
opt.Apply(s)
@@ -1213,6 +1226,9 @@ func (s *Server) applyOptions(ctx *reloadContext, opts []option) {
if opt.IsAuthChange() {
reloadAuth = true
}
if opt.IsTLSChange() {
reloadTLS = true
}
if opt.IsClusterPermsChange() {
reloadClusterPerms = true
}
@@ -1256,9 +1272,55 @@ func (s *Server) applyOptions(ctx *reloadContext, opts []option) {
s.updateRemoteLeafNodesTLSConfig(newOpts)
}
if reloadTLS {
// Restart OCSP monitoring.
if err := s.reloadOCSP(); err != nil {
s.Warnf("Can't restart OCSP Stapling: %v", err)
}
}
s.Noticef("Reloaded server configuration")
}
func (s *Server) reloadOCSP() error {
opts := s.getOpts()
s.mu.Lock()
ocsps := s.ocsps
s.mu.Unlock()
// Stop all OCSP Stapling monitors in case there were any running.
for _, oc := range ocsps {
oc.stop()
}
// Restart the monitors under the new configuration.
ocspm := make([]*OCSPMonitor, 0)
if config := opts.TLSConfig; config != nil {
tc, mon, err := s.NewOCSPMonitor(config)
if err != nil {
return err
}
// Check if an OCSP stapling monitor is required for this certificate.
if mon != nil {
ocspm = append(ocspm, mon)
// Override the TLS config with one that follows OCSP.
s.optsMu.Lock()
s.opts.TLSConfig = tc
s.optsMu.Unlock()
s.startGoRoutine(func() { mon.run() })
}
s.Noticef("OCSP Stapling enabled for client connections")
}
// Replace stopped monitors with the new ones.
s.mu.Lock()
s.ocsps = ocspm
s.mu.Unlock()
return nil
}
// Update all cached debug and trace settings for every client
func (s *Server) reloadClientTraceLevel() {
opts := s.getOpts()

View File

@@ -236,6 +236,9 @@ type Server struct {
// MQTT structure
mqtt srvMQTT
// OCSP monitoring
ocsps []*OCSPMonitor
// exporting account name the importer experienced issues with
incompleteAccExporterMap sync.Map
@@ -1467,6 +1470,29 @@ func (s *Server) fetchAccount(name string) (*Account, error) {
return acc, nil
}
func (s *Server) enableOCSP() error {
opts := s.getOpts()
// Start OCSP Stapling for client connections.
if config := opts.TLSConfig; config != nil {
tc, mon, err := s.NewOCSPMonitor(config)
if err != nil {
return err
}
// Check if an OCSP stapling monitor is required for this certificate.
if mon != nil {
s.ocsps = append(s.ocsps, mon)
// Override the TLS config with one that follows OCSP.
opts.TLSConfig = tc
s.startGoRoutine(func() { mon.run() })
}
s.Noticef("OCSP Stapling enabled for client connections")
}
// FIXME: Add support for leafnodes, routes, MQTT, WebSocket
return nil
}
// Start up the server, this will block.
// Start via a Go routine if needed.
func (s *Server) Start() {
@@ -1619,6 +1645,13 @@ func (s *Server) Start() {
})
}
// Setup OCSP Stapling. This will abort server from starting if there
// are no valid staples and OCSP policy is to Always or MustStaple.
if err := s.enableOCSP(); err != nil {
s.Fatalf("Can't enable OCSP Stapling: %v", err)
return
}
// Start monitoring if needed
if err := s.StartMonitoring(); err != nil {
s.Fatalf("Can't start monitoring: %v", err)

View File

@@ -0,0 +1,34 @@
-----BEGIN CERTIFICATE-----
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
-----END CERTIFICATE-----

View File

@@ -0,0 +1,51 @@
-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----

View File

@@ -0,0 +1,34 @@
-----BEGIN CERTIFICATE-----
MIIF2TCCA8GgAwIBAgIBATANBgkqhkiG9w0BAQsFADCBizELMAkGA1UEBhMCVVMx
CzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1TYW4gRnJhbmNpc2NvMRAwDgYDVQQKDAdT
eW5hZGlhMRAwDgYDVQQLDAduYXRzLmlvMRUwEwYDVQQDDAxsb2NhbGhvc3QgY2Ex
HDAaBgkqhkiG9w0BCQEWDWRlcmVrQG5hdHMuaW8wHhcNMjEwNTExMjAxMTM1WhcN
MjkxMDE0MjAxMTM1WjCBjzELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMRYwFAYD
VQQHDA1TYW4gRnJhbmNpc2NvMRAwDgYDVQQKDAdTeW5hZGlhMRAwDgYDVQQLDAdu
YXRzLmlvMRkwFwYDVQQDDBBsb2NhbGhvc3QgY2xpZW50MRwwGgYJKoZIhvcNAQkB
Fg1kZXJla0BuYXRzLmlvMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA
ul+i7nMo02miq32kfFzYeexKola5b4Cc1CY62x0IGbPgiFUoVGZAmDZGdiiERxOH
GJDODvZIjXZVdFwiZQGfL/t2gs+A0A61o2RDKcfe57mW9FGLyjiPMAGaeYddiSOx
/CK0/gDjRrcloQkRDiXbyjAUNgoMW7W7g4ArpOpZkpJIqrTq7aZXJzhbdU6tHbTN
lkPgzNsLmMUrmg10gesoajIXVJc6aQ2qdfuskXrtAEVDCFmIAV9cZqt2uWs3erEK
lIgYffjlyTGoXF8jQLkSChEGYtyZ0ov1e+wBjltpgw+GRwrBM+NIeRuTilpB4Agb
yEkAXkryzfuGePhwB1qGG7Qy73qKdHctwiO0vBpqylBQNgyl4IaD33NLkDUtLly7
Ti9VxBlV7H3HWofpx1/AUtCfxfGg3pz+wZQuUWZPhQTV8zxDJOOtWZyDKKT9W6Tm
2XF7CoNhzGtc+NtatqJ4xDuzco9Mvh3q5ERXYqycNbmNldrVtkzMm258UuLITu7m
zAMqh4CnDM/8UIOWc1Ovrv1vJmxI0ZGSywSlXX0j0jE63QqVlWwsQBdOdK86R7X3
Db6sNY/gnnOjY9Q9N/bEgRKm0zFlFvvGbmnbEbq1ShOXeNc3DmK3N/qJpuxJzMVu
fIQ8kcwz4fX0efZbayq0WOMeargM/2IVOZ7rsbam1KkCAwEAAaNCMEAwCQYDVR0T
BAIwADALBgNVHQ8EBAMCBeAwJgYDVR0RBB8wHYIJbG9jYWxob3N0ghBjbGllbnQu
bG9jYWxob3N0MA0GCSqGSIb3DQEBCwUAA4ICAQAZsO7juFWr0tMY2Bm1Y0gSfcMZ
seDv+XBvKLX3lKYE2TgQrY3IJz9wL/6okzb8wlwA6GOYoir4TMFRDsaItvkkFZc+
Z2xGiI+RyhVPxPo39DY4/p8fWVGuAGzNsSIsk9Qu9OBAhWizmzAh5+t7vo9vpHOu
sZlFO9QSCpfQksCOLwCFz3wjJxFtDUhY/+i0rOOddylbjwPJNO2j8f0eukjXY37k
7AAUB9nDRl+t8pmm8s5R46LZgiWvZm8COeCG6aESfkBBex7peCPG5pr7n46oK2gu
CrWFbuTJ6JDs0RvKw04kQi9C7dR71i0qPDmusnV9y/E3gyXgwNYcDlC2hRW1vRPt
hp6KCLdc+l4bs8sqbNvusi5GjJ+EhORY8mfzN5w6/gCEYzrnXIzJfqXjsKMC62xB
sToTXpG9Hcdt7KrlYL+GXvmEWHwu4p6MyjmyFAmqjAWfr5tbYlK4XgzeUX6MCrXW
tMe6OxOI0+jqevziFf1ITWvwz+4G/x6NuBQf1pgajxvFfm5Mtvu+/J+jP8TCDjl3
55ZJkfSiPiGFCO/yYd17CTzsgWiMzn/J50Gd9/k39CiMtPXAils08v4BM7RmdPSi
2y/c//FO+J9YSI7i2mdd0JoDsx4gH//SGVSbrAZeTNCXoiqG2G7dsBpVEOKbFPIn
NejC2QUTFLwq9vfjyA==
-----END CERTIFICATE-----

View File

@@ -0,0 +1,51 @@
-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----

View File

@@ -0,0 +1,34 @@
-----BEGIN CERTIFICATE-----
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
IKBPu3vS3nsv67DyBA==
-----END CERTIFICATE-----

View File

@@ -0,0 +1,51 @@
-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----

View File

@@ -0,0 +1,35 @@
-----BEGIN CERTIFICATE-----
MIIGCjCCA/KgAwIBAgIBAzANBgkqhkiG9w0BAQsFADCBizELMAkGA1UEBhMCVVMx
CzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1TYW4gRnJhbmNpc2NvMRAwDgYDVQQKDAdT
eW5hZGlhMRAwDgYDVQQLDAduYXRzLmlvMRUwEwYDVQQDDAxsb2NhbGhvc3QgY2Ex
HDAaBgkqhkiG9w0BCQEWDWRlcmVrQG5hdHMuaW8wHhcNMjEwNTExMjAxMTM1WhcN
MjkxMDE0MjAxMTM1WjCBnjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMRYwFAYD
VQQHDA1TYW4gRnJhbmNpc2NvMRAwDgYDVQQKDAdTeW5hZGlhMRAwDgYDVQQLDAdu
YXRzLmlvMSgwJgYDVQQDDB9sb2NhbGhvc3Qgc2VydmVyIHN0YXR1cyByZXF1ZXN0
MRwwGgYJKoZIhvcNAQkBFg1kZXJla0BuYXRzLmlvMIICIjANBgkqhkiG9w0BAQEF
AAOCAg8AMIICCgKCAgEAou+lxMBr5LpB6o6ZZ5S2najkJWYm555IEz5DlnCNxkX3
UfDaO9StTSlJscc7ZwtmOF1aSAqwnI6KTV43Te5qSU0DolyPTPwBECjr5G4PgRJk
tvBaqCUrdc6PXcwHEUDukWw5G8XxJ73UZuIuwvCg/ZRsOO3V9XYL+Q9chdXS/W/Q
ZCY4bOb/7AJoD7VuUKQp6KY9ptnqdmDsRAlWiKjtW9HPpldzLwLG/J5s4TVHrU+2
T1or+hywSKqzcjeJFAaPTsfKGdDiYAuW3yy7YlYdebsjlldGhi3Xo5J4FiAgyPa4
I2RVdEPVa8VmOKoEbdfEL3KVmB57KmnmnDiqLpCYxyx51GvE1Opf5mi1QH8gQ0cw
r7mJqsms99A+wyBojgdAYxZa+tDcZcZTj4v0r/9OdKu+vTkVIPr2OYPprWE0PfGJ
efDILOfRrmY8OqbWLDe5d2WEVhaGHoXtxlNoUrTUY6SRW+dvubiBcQIYkWnk1c/e
p/c7zkgCicJmBQdjDcNEiadTT7r0gHIoJO2bMKSqb7gz0IBqVOl409hn2FhxNgh1
mt4MlXl5FH5rCTUsNSR8va7r5IVNbdK6wUIfRtyLUBnDFYKR6qN8UwvPfr8JWsvZ
zT2jDcBWYabAj521KHqo0hwItW9JcD/CO0M43rPq18YzsYIR00IU8FJ7zVz7olEC
AwEAAaNkMGIwCQYDVR0TBAIwADALBgNVHQ8EBAMCBeAwEQYIKwYBBQUHARgEBTAD
AgEFMDUGA1UdEQQuMCyCCWxvY2FsaG9zdIIfc2VydmVyLXN0YXR1cy1yZXF1ZXN0
LmxvY2FsaG9zdDANBgkqhkiG9w0BAQsFAAOCAgEAVGa9luluxfm2FU5Plo/53tys
dA1IurRs+294adJBKc+LJtZIZjCW74KmqNvlN+UKC857STjnMi1fjSHyJKRpNLfo
wyMax7G3SCbOYnNjsbMgub9BoGlGqUgdU98av3SS7dyfJ5jgeiNfNrt3RUBGZpYE
70+d+m671dPhFlpXDTlRKpbdmCno5KfMDne+aLmTsZq2D0WYpjjAXJLIlexcF6KI
1Pz+VgthkqfPczSE0CMTAtL/zuOD6c4RqtYX8Q8A5E3U09mNo7kybVvLZrQPPAfZ
vbFbPwv4qZMRZ6ZXZiNTGXXnPNbE66/Ce+Jm7TKZrrfShG7ObUmyKI+X8tObCssd
xHKn59Fe5AL+gu6gzy6wC0wfBIH5gPMtkHwg9thhKd/T02LbL5iOXHIUhAVfk6qB
h3+9GaY6eu4yhU0/C9Qrnoq8QAWM8eqiaJ0i2f9rhbs1o5Yp4NX/fD5T9jcok9+L
BE34BGO6l0b01TVvfssiYmH7a0YYO3xVMy6IgJg7hBTVIXLqFLEKfrj+rNai6Th3
vv5rjkbJh4f3wzm5+uCFqM8BUBbJ/k5Pz/8qM105IbM89maW56R0DhsFZdMxOI+7
gXee7BH3cBS9LcYhAgNIwF7lVOQX62dF3rYvIdkGEWjEouteno2SZRtKHNsSvviW
8PTvHAb9z7LxEYEjwC4=
-----END CERTIFICATE-----

View File

@@ -0,0 +1,51 @@
-----BEGIN RSA PRIVATE KEY-----
MIIJJwIBAAKCAgEAou+lxMBr5LpB6o6ZZ5S2najkJWYm555IEz5DlnCNxkX3UfDa
O9StTSlJscc7ZwtmOF1aSAqwnI6KTV43Te5qSU0DolyPTPwBECjr5G4PgRJktvBa
qCUrdc6PXcwHEUDukWw5G8XxJ73UZuIuwvCg/ZRsOO3V9XYL+Q9chdXS/W/QZCY4
bOb/7AJoD7VuUKQp6KY9ptnqdmDsRAlWiKjtW9HPpldzLwLG/J5s4TVHrU+2T1or
+hywSKqzcjeJFAaPTsfKGdDiYAuW3yy7YlYdebsjlldGhi3Xo5J4FiAgyPa4I2RV
dEPVa8VmOKoEbdfEL3KVmB57KmnmnDiqLpCYxyx51GvE1Opf5mi1QH8gQ0cwr7mJ
qsms99A+wyBojgdAYxZa+tDcZcZTj4v0r/9OdKu+vTkVIPr2OYPprWE0PfGJefDI
LOfRrmY8OqbWLDe5d2WEVhaGHoXtxlNoUrTUY6SRW+dvubiBcQIYkWnk1c/ep/c7
zkgCicJmBQdjDcNEiadTT7r0gHIoJO2bMKSqb7gz0IBqVOl409hn2FhxNgh1mt4M
lXl5FH5rCTUsNSR8va7r5IVNbdK6wUIfRtyLUBnDFYKR6qN8UwvPfr8JWsvZzT2j
DcBWYabAj521KHqo0hwItW9JcD/CO0M43rPq18YzsYIR00IU8FJ7zVz7olECAwEA
AQKCAgBlEBRYJ6pEoysDnBOW5e0neXyZnfT/sXOvS+2MQKAPnZI8JxKWDeK4e6WU
OamkzrNGvtCi4s6NLPSn7IqNMhaHBNf+Oz8/Vwgpx9gZRhMj0g7aUddJeFSuq8LN
QSIZF5diaCg8C9j694npjt3GWI7i+s7tuMf/ior+nwKamPhX7qTpmbNiCR4we4Wk
SLr2Ff1QqtyOw5fkeVXTFZ+xAGbJjygnWxK81BIs2u9Z+TxOSaUhLyMb7fOB/y9y
5vOFklQNX2sB/EiNnmKkZxCLfDKoMOVv+Q5rZ7/bW5xUzPTI8g9hFHjUtsaIJFa1
Su+YWj771yzmv/FRa4J438TfQR0hX9GYfvsgxmKAyAoc2TbcppVzZo20Vtdjm1Pn
eqUhSXJYCmOJRbdvxIpsq8iWJGvgyZajC6qVEc2ycnoitNxdpfQEEnuVYTZ59cKO
4nSKv04XqhHmsSuL2VuakaJMKKMmxLdB+r/JFrnhXp7P/w8CUcUFXvlmLegCODPq
jkBB2WobcO5vYjjp0ApgNVs3WiSnEP9KYQ/5JDYtMrHqAZ+PBsnLLdfzBYO5RlpK
ml6CkdRUi7q7h+Q89DVUVuqh8elRQMo+43CwwGSUsOr4rHCLiIGlUOc2Jvuc6BJT
1zVfRgnm6GpcvYzljvpzkqChPqDNIyHVi+Y22EakdKB0MPoKCQKCAQEA1m306dmV
HWXO2BlH5rlrrA+5aGvKosajPaBdOm+wqvt7y1TGOMOhCLNg9o0VvDyQe374rw/4
Xn9m6RE/Ns/P3CSd3Ybmx5MLCgSRRqHv7KF9ymK06jNNlsNu2kxxMCMFM6/nRVlA
7SkjUI4XYYmr+9+miXlRl2ahk7HoAi/i+TrGgULxbiOid20cONj/HUcIrY2d6Qss
ynWIsuBCZRY+ie4pEoxKnxqX1PsORFOuiKIqo/2IyaerlAn/Bol2Tpx1sccDSE2J
BvwaF7+N54qYKfnGJU+ThxagUgdWpcn9gi/4GUgSW7fa9zROFr5zNAID9BQuvtfz
UKcxWc+IhqpmawKCAQEAwoYYnG85flYUuj5oS38aBk0/WDNu5C8adBDIoS9qXIk2
D0MX6BxCu160LlEOsw4HknVek/xC/velZi5CkSAo/wbcT7b3LGZrXCN615+6o1TK
r/d+UKwPafkoS7j1Y0tc9J1y9TsjS0UBwM4o+4cZjM+9oM3Aq9WOEvr7hARf9/+u
PxqulBqDAo0VrlNzbn/5Q1A2mCm534LzbWEDslQSsq5geogCBIIjrOdj+BTDarnz
O5qd3fva51pJ0eRHMu+6PK9hWnncHobQyw3TzPhrMF8HCoshKS3LgozWT+oekWJw
RV+u+sVRWFLdDroNZFz7pctE27aANywYM4ZwonxxMwKCAQBxb6324EJAURGBxK4C
4uiRF6hwE0YZopfNDD8FoPyHF48/29MZSHSyU6LiC3UKJcgRbPRGOF6eLyvT9GnK
p1lBDqXtAWapAaL/Y7cu9JAmULBpFpq6ovVS4oSMO5BNdNlVpKLmTvdH/1FNVj4M
PXacQo6pf2Kog4TKy3z/WzHpwywsSavLJlLWdwRNFo6vgFqY5ag6Fs1VNaRhbL3z
GDdxZGqaA1mencTgyQedId/dLFz+cCui8m6UXE1rueC6aY7hw3R7FXl+FnP/SDjb
2rfwzNAEAPr8pf2eJ3+xKRBRhOrtBPGhT7wotqTw50OuqbpJrzujfj6b1jcHWgDR
rOeNAoIBAHA2BIpxCrxbEbfh+i3a0vthojHR8Z0Fov/jEqkQfg2FRT8GmArYCpKl
bdDuB0m4xRtyQy2grlEAMFRCSToIUD3VCk+dnvXo2vOar+kkhfhkGEvru9zzdCzQ
grMzrbIqriOZk8/s3k40L2+2PSPjahS1XZEeP4+gMEW4rFAaafXYcv6J+L0Mkhht
pF0cXJEYl4SCCAw8vbE2jA/Dj+tV3jdeqd7lCCzrmYLLM/rOl2/AdpQifACqoTsl
9UFzqrKyYT9SeBlGBHlDkbwgbNZnUwXjO1+UpHtppGTZs2MEDcAWBeeu63RTULpf
io9NOh50GOIp4L3RiCLLd+Z5Hg5NNMsCggEAGfkqZTLs0tuD5VOypOPVx6QQi/iG
GeFdoAFPsINztTfbRZ8iU6r3wK5iv/B91fMeMkNwxFx8xwlypIf50DzY+OxFhPsL
I6AlmDm/VxYZxIjdThQslh6zhTu9JeW5HJ4oQnKz5JtAzjEdEPvOnRgAkxAjQ1x7
RNnt2peWZCHh9zeJyP3ZH0m1Q/L+ESqzovR/TmqNfdjMvAPrtMc2Hr2XP04lJBiw
RgZOrb8giFCHg7n5KCpon2Udf5E7S6X2oYbjz0ImXGStycW/NPGcjcqRGqIyDpB0
z8eKdxxa8SZm1Im9sz+AYY5e60vRUyjInoPNM6wXd+E0tAOlUsM6Yemvpw==
-----END RSA PRIVATE KEY-----

View File

@@ -0,0 +1,70 @@
-----BEGIN CERTIFICATE-----
MIIGTDCCBDSgAwIBAgIBAjANBgkqhkiG9w0BAQsFADCBizELMAkGA1UEBhMCVVMx
CzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1TYW4gRnJhbmNpc2NvMRAwDgYDVQQKDAdT
eW5hZGlhMRAwDgYDVQQLDAduYXRzLmlvMRUwEwYDVQQDDAxsb2NhbGhvc3QgY2Ex
HDAaBgkqhkiG9w0BCQEWDWRlcmVrQG5hdHMuaW8wHhcNMjEwNTExMjAxMTM1WhcN
MjkxMDE0MjAxMTM1WjCBpzELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMRYwFAYD
VQQHDA1TYW4gRnJhbmNpc2NvMRAwDgYDVQQKDAdTeW5hZGlhMRAwDgYDVQQLDAdu
YXRzLmlvMTEwLwYDVQQDDChsb2NhbGhvc3Qgc2VydmVyIHN0YXR1cyByZXF1ZXN0
IHdpdGggdXJsMRwwGgYJKoZIhvcNAQkBFg1kZXJla0BuYXRzLmlvMIICIjANBgkq
hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA4IEf3ITJxeRTEYSXJ13LS8rvoOyRrQTo
mGSSIWzkvs9ELJN/C7AtWy98m+0+lpdtaQLLZaY/hdh6Wu7tqJ0LS8axz9vWXkjr
GoPCV2MedhQG4+P6zDXQaJyEBfW1kchZY+O8Lm/MHKITp3soo6To4J+sIbzg9XQt
Yxl38HaPEwDP2xn0FkY/0HhaSYuoAo+K/bQ1tVj7vnSgvZtUWDvu5NhkyEx7qJxL
/cNfUPGadyetB3rKZfQGgYMfxu7dl5bB5yJwYVOx7uzAN4bjejUtSZ+E8xarliSH
0hxPbekIeSayMfyWp/XYtQ+hENSAnhsSUgezlQ++yl1Al9XLiwELRDTaehbBGjAB
zhnqkpOTxG5Eg220MKD8xyqLWuZTDSHBukOXVHGsr3ct1PRjJ1CH7WIfyzUuq9IH
eVCfGcNaO7BjqJKChGwJGLFVdqfoJqi7vc2475SKvkVa/jbNMyXw/ic0POV9frdg
Nkwxm6jXGeNJ7jaJND02eSinY/glf6Ed1aRK7FEuyh8oM73JmAlJ6up0Axr349HG
Uu6XaUjKCJy/eTwkEaDyeyQRHgsYj2fpl8uGui8CSrBK3+Ha9ai5Ie2LNzI81khq
2ZLH6wbg/Y3UJsTeoXrWhZOcin3z17KJkiOGbsUBntac4ClfMwKNlF1NcUOp6EQh
0N7tXhnimpMCAwEAAaOBnDCBmTAJBgNVHRMEAjAAMAsGA1UdDwQEAwIF4DAxBggr
BgEFBQcBAQQlMCMwIQYIKwYBBQUHMAGGFWh0dHA6Ly8xMjcuMC4wLjE6ODg4ODAR
BggrBgEFBQcBGAQFMAMCAQUwOQYDVR0RBDIwMIIJbG9jYWxob3N0giNzZXJ2ZXIt
c3RhdHVzLXJlcXVlc3QtdXJsLmxvY2FsaG9zdDANBgkqhkiG9w0BAQsFAAOCAgEA
Vbc6tBhSLLS2/1sYzpjDn293nvBruNeConbj3GmjdFqkp3iD2jsVilLYZbgQfjJY
KEzWXYEXWTtpcpTxVFZFZwdc1C5oMmhUsUOkm7eEcVn5+oGR8k/kQ+pbSQQd3Ii8
uqZ3Z8vmD3kItM/8MWWGUdpNjqLwronTTO4XfqPLYtNIeFd6pjLmY3xMopOzl5G/
PY8010e8ZMU5xCzYCJ73vc8bhQMevoMuJFfNEzWWQiKwy74lAiJObIQ8wHkIgaa5
mrBl7oU7dvuz22eaItCY04DO06A5e3QJKOBsW0NOjcKRw6sHXbVtU1hp0CUsxcrz
HCttM22Pmi/8u+0blmWPHK5cPQoPQsks6QOXD8Ecp74oxB9sbJNUIJ3KJSkUZqUW
T/sbQhqHe/6DGEbl4WWpPsvBp2HRHOhaLlE3tPVLDSQE55mMpaSfeC6FjHvW38MD
aG6rGRI6Y9ibJBHEcy12kPo6APjSPtIGrAdCKBGBgUothKiiWAx/6ul+sKhzSL4N
iFjNODYdwwUxlINyX3jqSyHLjq5QFNH+aF1NOou1D1qbrDhzWJ09u1FrpNRTtf0F
2sAfEPihQu5DxnODqbwH5YOSNfGNXQXbY6JxZE7a5VCfocHa6u/uhN6jJg+aNllM
rTV3nI+hWq4RtvQnqAyuhMkX2q/T+QaRugRtJ1ywUtE=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIF+TCCA+GgAwIBAgIUOZOobSCn5WL7fGjMTas5i191p8kwDQYJKoZIhvcNAQEL
BQAwgYsxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEWMBQGA1UEBwwNU2FuIEZy
YW5jaXNjbzEQMA4GA1UECgwHU3luYWRpYTEQMA4GA1UECwwHbmF0cy5pbzEVMBMG
A1UEAwwMbG9jYWxob3N0IGNhMRwwGgYJKoZIhvcNAQkBFg1kZXJla0BuYXRzLmlv
MB4XDTIxMDUxMTIwMTEzM1oXDTIxMDYxMDIwMTEzM1owgYsxCzAJBgNVBAYTAlVT
MQswCQYDVQQIDAJDQTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzEQMA4GA1UECgwH
U3luYWRpYTEQMA4GA1UECwwHbmF0cy5pbzEVMBMGA1UEAwwMbG9jYWxob3N0IGNh
MRwwGgYJKoZIhvcNAQkBFg1kZXJla0BuYXRzLmlvMIICIjANBgkqhkiG9w0BAQEF
AAOCAg8AMIICCgKCAgEAs1szTYUBy7GPQnDaH5863bEVldI2xxNa5xZalaNywI+H
z058zxuvsDeR2gmcgfZM4kuLW7eDL0IjPHmJfklS8GhoN5ZuzFSY5EHGqBKTfX0Z
vvl1aNZo2GGaPgnR+EbC9NjxdsVcEkfkW9pWC2NXqdCISHiv3uh5IjyfAjxDS/t7
sngSyrYF+L4HCJ7rbOnfCpzfYD48Rw5l76wGzN05dAjElU8Y/0mbX6H8GPKQ7mZZ
K8z5OIHwioQmHf9KxKl870pZQKm+u3pDIhBNweH8TNr6AuI8n2YbCfC+HyjjV041
Xprh26Y145xqQvlIoPHZtEPK94mF0w92sE79jX8mZ1LbQlDcBzpvqXaC/YwaRYgf
82/51UNY/xSYxg2vkmie6l7dDMIVMmmFUs2ZOOFxuwo3ikls8Tx0FlnIUkBjobuA
cc1MN9Opva1G9j977UocmTe0T23hEOcqYdoLJ5WM/l6b29h8+74xhws2SFkQh2Lb
CLLFfelK3wpIyequ4DzHwLfyLhqasRWE4ac9Q04G5NR+T3QKMuVCxcTEREsLk/5S
hwqZoFc8zyIT/9cVRuUtTzM/EOQq4c7CKKcE4NGJb0a+hR6drvWmYi9Zsgt1sRC3
bSsxXUaAPQE8/tVdEBW97TNA3yK9THfHPV1MUQNCbw3FIW+qIYBQISjKatvGJD8C
AwEAAaNTMFEwHQYDVR0OBBYEFCPCNWQ7F7gS6gt1zIprz5405GmQMB8GA1UdIwQY
MBaAFCPCNWQ7F7gS6gt1zIprz5405GmQMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI
hvcNAQELBQADggIBAEI3tPoBKh026z1V2zNLNP9L+ZNcrbA1Yw74DOIOVs6InnuM
Grxjy9zYdNXQs5UOtDsPvH8e2u1mpS/es24GnTXA0LLkS0gCcKaaDdzTnEr4zCOn
khogeOZphY7UCX1SAi7qVrwcRXOWdSxSrAaQY17gl7Ln+W4QTWjIyNpweZIKAMu4
60kIJYteNCnXgE5WppW7qICYdHapJz8/sJzqrtlPTR2PnmW1+aiWF86KeEFnXAai
60PNHojVbd7/U2425x4oZQRGoZ1/5azs8w2X/bidshwtz/kYtHPBP4Xzt3c6M92v
HDwpa9wIrvRoQxmUGWjPcZkVvm53ZIU/YYxQ+ueJkuS3Eloh4bP1kNKDDXKZWzmT
Oo8q3K0lnPlTAjeX5nVgkDuKq1WG+DdCp5VVAsVsOnl/fRN6N7230PfNTudazgSR
UjOLE6HsZDGYemdZJaydmQNvCWjBwRAlqd7IdmCtBSZVtxTZ88VLT6R85QzOWn9G
eCxNaJLeBBanR8HG/dFtMf1kzJ0csTwWnituG4inhE+90J2UmaBSrLbUJdbwrG66
j1njHQH6WpEswg48XtLB8OuYh8YJs7+yCX7S1l8q/NaPUGZadg1nPR5mokcf4VvW
rrEcTc9ma9VUszgm518FE+Ibb5zQeK6YFhBU29JjcdATUK4RzglWt7mtrfxr
-----END CERTIFICATE-----

View File

@@ -0,0 +1,36 @@
-----BEGIN CERTIFICATE-----
MIIGTDCCBDSgAwIBAgIBAjANBgkqhkiG9w0BAQsFADCBizELMAkGA1UEBhMCVVMx
CzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1TYW4gRnJhbmNpc2NvMRAwDgYDVQQKDAdT
eW5hZGlhMRAwDgYDVQQLDAduYXRzLmlvMRUwEwYDVQQDDAxsb2NhbGhvc3QgY2Ex
HDAaBgkqhkiG9w0BCQEWDWRlcmVrQG5hdHMuaW8wHhcNMjEwNTExMjAxMTM1WhcN
MjkxMDE0MjAxMTM1WjCBpzELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMRYwFAYD
VQQHDA1TYW4gRnJhbmNpc2NvMRAwDgYDVQQKDAdTeW5hZGlhMRAwDgYDVQQLDAdu
YXRzLmlvMTEwLwYDVQQDDChsb2NhbGhvc3Qgc2VydmVyIHN0YXR1cyByZXF1ZXN0
IHdpdGggdXJsMRwwGgYJKoZIhvcNAQkBFg1kZXJla0BuYXRzLmlvMIICIjANBgkq
hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA4IEf3ITJxeRTEYSXJ13LS8rvoOyRrQTo
mGSSIWzkvs9ELJN/C7AtWy98m+0+lpdtaQLLZaY/hdh6Wu7tqJ0LS8axz9vWXkjr
GoPCV2MedhQG4+P6zDXQaJyEBfW1kchZY+O8Lm/MHKITp3soo6To4J+sIbzg9XQt
Yxl38HaPEwDP2xn0FkY/0HhaSYuoAo+K/bQ1tVj7vnSgvZtUWDvu5NhkyEx7qJxL
/cNfUPGadyetB3rKZfQGgYMfxu7dl5bB5yJwYVOx7uzAN4bjejUtSZ+E8xarliSH
0hxPbekIeSayMfyWp/XYtQ+hENSAnhsSUgezlQ++yl1Al9XLiwELRDTaehbBGjAB
zhnqkpOTxG5Eg220MKD8xyqLWuZTDSHBukOXVHGsr3ct1PRjJ1CH7WIfyzUuq9IH
eVCfGcNaO7BjqJKChGwJGLFVdqfoJqi7vc2475SKvkVa/jbNMyXw/ic0POV9frdg
Nkwxm6jXGeNJ7jaJND02eSinY/glf6Ed1aRK7FEuyh8oM73JmAlJ6up0Axr349HG
Uu6XaUjKCJy/eTwkEaDyeyQRHgsYj2fpl8uGui8CSrBK3+Ha9ai5Ie2LNzI81khq
2ZLH6wbg/Y3UJsTeoXrWhZOcin3z17KJkiOGbsUBntac4ClfMwKNlF1NcUOp6EQh
0N7tXhnimpMCAwEAAaOBnDCBmTAJBgNVHRMEAjAAMAsGA1UdDwQEAwIF4DAxBggr
BgEFBQcBAQQlMCMwIQYIKwYBBQUHMAGGFWh0dHA6Ly8xMjcuMC4wLjE6ODg4ODAR
BggrBgEFBQcBGAQFMAMCAQUwOQYDVR0RBDIwMIIJbG9jYWxob3N0giNzZXJ2ZXIt
c3RhdHVzLXJlcXVlc3QtdXJsLmxvY2FsaG9zdDANBgkqhkiG9w0BAQsFAAOCAgEA
Vbc6tBhSLLS2/1sYzpjDn293nvBruNeConbj3GmjdFqkp3iD2jsVilLYZbgQfjJY
KEzWXYEXWTtpcpTxVFZFZwdc1C5oMmhUsUOkm7eEcVn5+oGR8k/kQ+pbSQQd3Ii8
uqZ3Z8vmD3kItM/8MWWGUdpNjqLwronTTO4XfqPLYtNIeFd6pjLmY3xMopOzl5G/
PY8010e8ZMU5xCzYCJ73vc8bhQMevoMuJFfNEzWWQiKwy74lAiJObIQ8wHkIgaa5
mrBl7oU7dvuz22eaItCY04DO06A5e3QJKOBsW0NOjcKRw6sHXbVtU1hp0CUsxcrz
HCttM22Pmi/8u+0blmWPHK5cPQoPQsks6QOXD8Ecp74oxB9sbJNUIJ3KJSkUZqUW
T/sbQhqHe/6DGEbl4WWpPsvBp2HRHOhaLlE3tPVLDSQE55mMpaSfeC6FjHvW38MD
aG6rGRI6Y9ibJBHEcy12kPo6APjSPtIGrAdCKBGBgUothKiiWAx/6ul+sKhzSL4N
iFjNODYdwwUxlINyX3jqSyHLjq5QFNH+aF1NOou1D1qbrDhzWJ09u1FrpNRTtf0F
2sAfEPihQu5DxnODqbwH5YOSNfGNXQXbY6JxZE7a5VCfocHa6u/uhN6jJg+aNllM
rTV3nI+hWq4RtvQnqAyuhMkX2q/T+QaRugRtJ1ywUtE=
-----END CERTIFICATE-----

View File

@@ -0,0 +1,51 @@
-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----

1039
test/ocsp_test.go Normal file

File diff suppressed because it is too large Load Diff