add unit test for cert PKCS12 DER PEM
This commit is contained in:
parent
6f4f86da79
commit
0ade6c177a
|
|
@ -73,13 +73,11 @@ var (
|
||||||
when use PEM/DER certificate file.`))
|
when use PEM/DER certificate file.`))
|
||||||
pCertFormat = flags.String("cert-format", string(lib.CertKeyFormatPEM), prettify(`
|
pCertFormat = flags.String("cert-format", string(lib.CertKeyFormatPEM), prettify(`
|
||||||
cert Format of given input (PEM, DER, PKCS12; heuristic if missing).`))
|
cert Format of given input (PEM, DER, PKCS12; heuristic if missing).`))
|
||||||
pass = flags.String("pass", "", prettify(`
|
certPass = flags.String("pass", "", prettify(`
|
||||||
Pass phrase for the key`))
|
Pass phrase for the PKCS12 cert`))
|
||||||
key = flags.String("key", "", prettify(`
|
key = flags.String("key", "", prettify(`
|
||||||
File containing client private key, to present to the server. Not valid
|
File containing client private key, to present to the server. Not valid
|
||||||
with -plaintext option. Must also provide -cert option.`))
|
with -plaintext option. Must also provide -cert option.`))
|
||||||
pKeyFormat = flags.String("key-format", string(lib.CertKeyFormatPEM), prettify(`
|
|
||||||
key Format of given input (PEM, DER; heuristic if missing).`))
|
|
||||||
|
|
||||||
// ALTS Options
|
// ALTS Options
|
||||||
usealts = flags.Bool("alts", false, prettify(`
|
usealts = flags.Bool("alts", false, prettify(`
|
||||||
|
|
@ -300,7 +298,7 @@ func main() {
|
||||||
usetls := !*plaintext && !*usealts
|
usetls := !*plaintext && !*usealts
|
||||||
cacertFormat := lib.NewCertificateKeyFormat(*pCACertFormat)
|
cacertFormat := lib.NewCertificateKeyFormat(*pCACertFormat)
|
||||||
certFormat := lib.NewCertificateKeyFormat(*pCertFormat)
|
certFormat := lib.NewCertificateKeyFormat(*pCertFormat)
|
||||||
keyFormat := lib.NewCertificateKeyFormat(*pKeyFormat)
|
keyFormat := lib.CertKeyFormatPEM
|
||||||
|
|
||||||
// Do extra validation on arguments and figure out what user asked us to do.
|
// Do extra validation on arguments and figure out what user asked us to do.
|
||||||
if *connectTimeout < 0 {
|
if *connectTimeout < 0 {
|
||||||
|
|
@ -330,55 +328,45 @@ func main() {
|
||||||
|
|
||||||
if usetls {
|
if usetls {
|
||||||
if *cacert != "" {
|
if *cacert != "" {
|
||||||
if cacertFormat.IsNone() {
|
guessFormat, err := lib.GuessFormatForFile(*cacert, cacertFormat)
|
||||||
guessFormat, err := lib.GuessFormatForFile(*cacert, "")
|
if err != nil {
|
||||||
if err != nil {
|
fail(nil, "Fail to guess file format of -key err: %s", err)
|
||||||
fail(nil, "Fail to guess file format of -key err: %s", err)
|
|
||||||
}
|
|
||||||
cacertFormat.Set(guessFormat)
|
|
||||||
}
|
}
|
||||||
switch cacertFormat {
|
switch guessFormat {
|
||||||
case lib.CertKeyFormatPEM, lib.CertKeyFormatDER:
|
case lib.CertKeyFormatPEM, lib.CertKeyFormatDER:
|
||||||
// do nothing
|
cacertFormat = guessFormat
|
||||||
default:
|
default:
|
||||||
fail(nil, "The -cacert-format %s not support.", keyFormat)
|
fail(nil, "The -cacert-format %s not support.", cacertFormat)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if *cert != "" {
|
if *cert != "" {
|
||||||
if certFormat.IsNone() {
|
guessFormat, err := lib.GuessFormatForFile(*cert, certFormat)
|
||||||
guessFormat, err := lib.GuessFormatForFile(*cert, "")
|
if err != nil {
|
||||||
if err != nil {
|
fail(nil, "Fail to guess file format of -cert err: %s", err)
|
||||||
fail(nil, "Fail to guess file format of -cert err: %s", err)
|
|
||||||
}
|
|
||||||
certFormat.Set(guessFormat)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch certFormat {
|
switch guessFormat {
|
||||||
case lib.CertKeyFormatPEM, lib.CertKeyFormatDER:
|
case lib.CertKeyFormatPEM, lib.CertKeyFormatDER:
|
||||||
if *cert == "" || *key == "" {
|
if *cert == "" || *key == "" {
|
||||||
fail(nil, "The -cert and -key arguments must be used together and both be present.")
|
fail(nil, "The -cert and -key arguments must be used together and both be present.")
|
||||||
}
|
}
|
||||||
|
certFormat = guessFormat
|
||||||
case lib.CertKeyFormatPKCS12:
|
case lib.CertKeyFormatPKCS12:
|
||||||
// do nothing
|
certFormat = guessFormat
|
||||||
default:
|
default:
|
||||||
fail(nil, "The -cert-format %s not support.", certFormat)
|
fail(nil, "The -cert-format %s not support.", certFormat)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if *key != "" {
|
if *certPass != "" {
|
||||||
if keyFormat.IsNone() {
|
switch certFormat {
|
||||||
guessFormat, err := lib.GuessFormatForFile(*key, "")
|
case lib.CertKeyFormatPKCS12:
|
||||||
if err != nil {
|
|
||||||
fail(nil, "Fail to guess file format of -key err: %s", err)
|
|
||||||
}
|
|
||||||
keyFormat.Set(guessFormat)
|
|
||||||
}
|
|
||||||
switch keyFormat {
|
|
||||||
case lib.CertKeyFormatPEM, lib.CertKeyFormatDER:
|
|
||||||
if *cert == "" || *key == "" {
|
|
||||||
fail(nil, "The -cert and -key arguments must be used together and both be present.")
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
fail(nil, "The -key-format %s not support.", keyFormat)
|
fail(nil, "The -pass argument is only supported when -cert-type is PKCS12.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if *key != "" {
|
||||||
|
if *cert == "" || *key == "" {
|
||||||
|
fail(nil, "The -cert and -key arguments must be used together and both be present.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -518,7 +506,7 @@ func main() {
|
||||||
}
|
}
|
||||||
creds = alts.NewClientCreds(clientOptions)
|
creds = alts.NewClientCreds(clientOptions)
|
||||||
} else if usetls {
|
} else if usetls {
|
||||||
tlsConf, err := lib.ClientTLSConfigV2(*insecure, *cacert, cacertFormat, *cert, certFormat, *key, keyFormat, *pass)
|
tlsConf, err := lib.ClientTLSConfigV2(*insecure, *cacert, cacertFormat, *cert, certFormat, *key, keyFormat, *certPass)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fail(err, "Failed to create TLS config")
|
fail(err, "Failed to create TLS config")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
package lib
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewCertificateKeyFormat(fileFormat string) CertificateKeyFormat {
|
||||||
|
fileFormat = strings.ToUpper(fileFormat)
|
||||||
|
switch fileFormat {
|
||||||
|
case "":
|
||||||
|
return CertKeyFormatNONE
|
||||||
|
case "PEM":
|
||||||
|
return CertKeyFormatPEM
|
||||||
|
case "DER":
|
||||||
|
return CertKeyFormatDER
|
||||||
|
case "JCEKS":
|
||||||
|
return CertKeyFormatJCEKS
|
||||||
|
case "PKCS12", "P12":
|
||||||
|
return CertKeyFormatPKCS12
|
||||||
|
default:
|
||||||
|
return CertKeyFormatNONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type CertificateKeyFormat string
|
||||||
|
|
||||||
|
const (
|
||||||
|
CertKeyFormatNONE CertificateKeyFormat = ""
|
||||||
|
// The file contains plain-text PEM data
|
||||||
|
CertKeyFormatPEM CertificateKeyFormat = "PEM"
|
||||||
|
// The file contains X.509 DER encoded data
|
||||||
|
CertKeyFormatDER CertificateKeyFormat = "DER"
|
||||||
|
// The file contains JCEKS keystores
|
||||||
|
CertKeyFormatJCEKS CertificateKeyFormat = "JCEKS"
|
||||||
|
// The file contains PFX data describing PKCS#12
|
||||||
|
CertKeyFormatPKCS12 CertificateKeyFormat = "PKCS12"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (f *CertificateKeyFormat) Set(fileFormat string) {
|
||||||
|
*f = NewCertificateKeyFormat(fileFormat)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f CertificateKeyFormat) IsNone() bool {
|
||||||
|
return f == CertKeyFormatNONE
|
||||||
|
}
|
||||||
|
|
@ -48,97 +48,42 @@ const (
|
||||||
fileHeader = "originFile"
|
fileHeader = "originFile"
|
||||||
)
|
)
|
||||||
|
|
||||||
var fileExtToFormat = map[string]string{
|
var fileExtToFormat = map[string]CertificateKeyFormat{
|
||||||
".pem": "PEM",
|
".pem": CertKeyFormatPEM,
|
||||||
".crt": "PEM",
|
".crt": CertKeyFormatPEM,
|
||||||
".cer": "PEM",
|
".p7b": CertKeyFormatPEM,
|
||||||
".p7b": "PEM",
|
".p7c": CertKeyFormatPEM,
|
||||||
".p7c": "PEM",
|
".p12": CertKeyFormatPKCS12,
|
||||||
".p12": "PKCS12",
|
".pfx": CertKeyFormatPKCS12,
|
||||||
".pfx": "PKCS12",
|
".jceks": CertKeyFormatJCEKS,
|
||||||
".jceks": "JCEKS",
|
".jks": CertKeyFormatJCEKS, // Only partially supported
|
||||||
".jks": "JCEKS", // Only partially supported
|
".der": CertKeyFormatDER,
|
||||||
".der": "DER",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var badSignatureAlgorithms = [...]x509.SignatureAlgorithm{
|
//var badSignatureAlgorithms = [...]x509.SignatureAlgorithm{
|
||||||
x509.MD2WithRSA,
|
// x509.MD2WithRSA,
|
||||||
x509.MD5WithRSA,
|
// x509.MD5WithRSA,
|
||||||
x509.SHA1WithRSA,
|
// x509.SHA1WithRSA,
|
||||||
x509.DSAWithSHA1,
|
// x509.DSAWithSHA1,
|
||||||
x509.ECDSAWithSHA1,
|
// x509.ECDSAWithSHA1,
|
||||||
}
|
//}
|
||||||
|
|
||||||
func errorFromErrors(errs []error) error {
|
//func errorFromErrors(errs []error) error {
|
||||||
if len(errs) == 0 {
|
// if len(errs) == 0 {
|
||||||
return nil
|
// return nil
|
||||||
}
|
// }
|
||||||
if len(errs) == 1 {
|
// if len(errs) == 1 {
|
||||||
return errs[0]
|
// return errs[0]
|
||||||
}
|
// }
|
||||||
buffer := new(bytes.Buffer)
|
// buffer := new(bytes.Buffer)
|
||||||
buffer.WriteString("encountered multiple errors:\n")
|
// buffer.WriteString("encountered multiple errors:\n")
|
||||||
for _, err := range errs {
|
// for _, err := range errs {
|
||||||
buffer.WriteString("* ")
|
// buffer.WriteString("* ")
|
||||||
buffer.WriteString(strings.TrimSuffix(err.Error(), "\n"))
|
// buffer.WriteString(strings.TrimSuffix(err.Error(), "\n"))
|
||||||
buffer.WriteString("\n")
|
// buffer.WriteString("\n")
|
||||||
}
|
// }
|
||||||
return errors.New(buffer.String())
|
// return errors.New(buffer.String())
|
||||||
}
|
//}
|
||||||
|
|
||||||
func NewCertificateKeyFormat(fileFormat string) CertificateKeyFormat {
|
|
||||||
fileFormat = strings.ToUpper(fileFormat)
|
|
||||||
switch fileFormat {
|
|
||||||
case "":
|
|
||||||
return CertKeyFormatNONE
|
|
||||||
case "PEM":
|
|
||||||
return CertKeyFormatPEM
|
|
||||||
case "DER":
|
|
||||||
return CertKeyFormatDER
|
|
||||||
case "PKCS12", "P12":
|
|
||||||
return CertKeyFormatPKCS12
|
|
||||||
default:
|
|
||||||
return CertKeyFormatNONE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type CertificateKeyFormat string
|
|
||||||
|
|
||||||
const (
|
|
||||||
CertKeyFormatNONE CertificateKeyFormat = ""
|
|
||||||
// The file contains plain-text PEM data
|
|
||||||
CertKeyFormatPEM CertificateKeyFormat = "PEM"
|
|
||||||
// The file contains X.509 DER encoded data
|
|
||||||
CertKeyFormatDER CertificateKeyFormat = "DER"
|
|
||||||
// The file contains JCEKS keystores
|
|
||||||
CertKeyFormatJCEKS CertificateKeyFormat = "JCEKS"
|
|
||||||
// The file contains PFX data describing PKCS#12
|
|
||||||
CertKeyFormatPKCS12 CertificateKeyFormat = "PKCS12"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (f *CertificateKeyFormat) Set(fileFormat string) {
|
|
||||||
*f = NewCertificateKeyFormat(fileFormat)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f CertificateKeyFormat) IsNone() bool {
|
|
||||||
return f == CertKeyFormatNONE
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *CertificateKeyFormat) SetPEM() {
|
|
||||||
*f = CertKeyFormatPEM
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f CertificateKeyFormat) IsPEM() bool {
|
|
||||||
return f == CertKeyFormatPEM
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f CertificateKeyFormat) IsDER() bool {
|
|
||||||
return f == CertKeyFormatDER
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f CertificateKeyFormat) IsPKCS12() bool {
|
|
||||||
return f == CertKeyFormatPKCS12
|
|
||||||
}
|
|
||||||
|
|
||||||
// ClientTLSConfigV2 builds transport-layer config for a gRPC client using the
|
// ClientTLSConfigV2 builds transport-layer config for a gRPC client using the
|
||||||
// given properties. Support certificate file both PEM and P12.
|
// given properties. Support certificate file both PEM and P12.
|
||||||
|
|
@ -147,7 +92,7 @@ func ClientTLSConfigV2(insecureSkipVerify bool, cacertFile string, cacertFormat
|
||||||
|
|
||||||
if clientCertFile != "" {
|
if clientCertFile != "" {
|
||||||
// Load the client certificates
|
// Load the client certificates
|
||||||
pemCertBytes, err := readAsPEMEx2(clientCertFile, string(certFormat), clientPass)
|
pemCertBytes, err := readAsPEMEx(clientCertFile, certFormat, clientPass)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("could not load client cert: %v", err)
|
return nil, fmt.Errorf("could not load client cert: %v", err)
|
||||||
}
|
}
|
||||||
|
|
@ -155,7 +100,7 @@ func ClientTLSConfigV2(insecureSkipVerify bool, cacertFile string, cacertFormat
|
||||||
|
|
||||||
// Load the client key
|
// Load the client key
|
||||||
if clientKeyFile != "" {
|
if clientKeyFile != "" {
|
||||||
pemBytes, err := readAsPEMEx2(clientKeyFile, string(keyFormat), clientPass)
|
pemBytes, err := readAsPEMEx(clientKeyFile, keyFormat, clientPass)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("could not load client key: %v", err)
|
return nil, fmt.Errorf("could not load client key: %v", err)
|
||||||
}
|
}
|
||||||
|
|
@ -174,13 +119,12 @@ func ClientTLSConfigV2(insecureSkipVerify bool, cacertFile string, cacertFormat
|
||||||
tlsConf.InsecureSkipVerify = true
|
tlsConf.InsecureSkipVerify = true
|
||||||
} else if cacertFile != "" {
|
} else if cacertFile != "" {
|
||||||
// Create a certificate pool from the certificate authority
|
// Create a certificate pool from the certificate authority
|
||||||
certPool := x509.NewCertPool()
|
pemCACertBytes, err := readAsPEMEx(cacertFile, cacertFormat, "")
|
||||||
pemCACertBytes, err := readAsPEMEx2(cacertFile, string(cacertFormat), "")
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("could not load cacert : %v", err)
|
return nil, fmt.Errorf("could not load cacert : %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Append the certificates from the CA
|
// Append the certificates from the CA
|
||||||
|
certPool := x509.NewCertPool()
|
||||||
if ok := certPool.AppendCertsFromPEM(pemCACertBytes); !ok {
|
if ok := certPool.AppendCertsFromPEM(pemCACertBytes); !ok {
|
||||||
return nil, errors.New("failed to append ca certs")
|
return nil, errors.New("failed to append ca certs")
|
||||||
}
|
}
|
||||||
|
|
@ -191,7 +135,12 @@ func ClientTLSConfigV2(insecureSkipVerify bool, cacertFile string, cacertFormat
|
||||||
return &tlsConf, nil
|
return &tlsConf, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GuessFormatForFile(filename, format string) (string, error) {
|
func GuessFormatForFile(filename string, format CertificateKeyFormat) (CertificateKeyFormat, error) {
|
||||||
|
// First, honor --format flag we got from user
|
||||||
|
if !format.IsNone() {
|
||||||
|
return format, nil
|
||||||
|
}
|
||||||
|
|
||||||
// Second, attempt to guess based on extension
|
// Second, attempt to guess based on extension
|
||||||
guess, ok := fileExtToFormat[strings.ToLower(filepath.Ext(filename))]
|
guess, ok := fileExtToFormat[strings.ToLower(filepath.Ext(filename))]
|
||||||
if ok {
|
if ok {
|
||||||
|
|
@ -200,7 +149,7 @@ func GuessFormatForFile(filename, format string) (string, error) {
|
||||||
|
|
||||||
file, err := os.Open(filename)
|
file, err := os.Open(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("unable to open file: %s\n", err)
|
return CertKeyFormatNONE, fmt.Errorf("unable to open file: %s\n", err)
|
||||||
}
|
}
|
||||||
defer file.Close()
|
defer file.Close()
|
||||||
reader := bufio.NewReaderSize(file, 4)
|
reader := bufio.NewReaderSize(file, 4)
|
||||||
|
|
@ -208,60 +157,60 @@ func GuessFormatForFile(filename, format string) (string, error) {
|
||||||
// Third, attempt to guess based on first 4 bytes of input
|
// Third, attempt to guess based on first 4 bytes of input
|
||||||
data, err := reader.Peek(4)
|
data, err := reader.Peek(4)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("unable to read file: %s\n", err)
|
return CertKeyFormatNONE, fmt.Errorf("unable to read file: %s\n", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Heuristics for guessing -- best effort.
|
// Heuristics for guessing -- best effort.
|
||||||
magic := binary.BigEndian.Uint32(data)
|
magic := binary.BigEndian.Uint32(data)
|
||||||
|
fmt.Printf(" magic 0x%0x\n", magic)
|
||||||
if magic == 0xCECECECE || magic == 0xFEEDFEED {
|
if magic == 0xCECECECE || magic == 0xFEEDFEED {
|
||||||
// JCEKS/JKS files always start with this prefix
|
// JCEKS/JKS files always start with this prefix
|
||||||
return "JCEKS", nil
|
return CertKeyFormatJCEKS, nil
|
||||||
}
|
}
|
||||||
if magic == 0x2D2D2D2D || magic == 0x434f4e4e {
|
if magic == 0x2D2D2D2D {
|
||||||
// Starts with '----' or 'CONN' (what s_client prints...)
|
// Starts with '----'
|
||||||
// TODO start with 'Certificate'
|
return CertKeyFormatPEM, nil
|
||||||
return "PEM", nil
|
}
|
||||||
|
if magic == 0x434f4e4e {
|
||||||
|
// Starts with 'CONN' (what s_client prints...)
|
||||||
|
return CertKeyFormatPEM, nil
|
||||||
|
}
|
||||||
|
if magic == 0x43657274 {
|
||||||
|
// Starts with 'Cert' (what openssl x509 -text -in tls/client.crt prints...)
|
||||||
|
return CertKeyFormatPEM, nil
|
||||||
}
|
}
|
||||||
if magic&0xFFFF0000 == 0x30820000 {
|
if magic&0xFFFF0000 == 0x30820000 {
|
||||||
// Looks like the input is DER-encoded, so it's either PKCS12 or X.509.
|
// Looks like the input is DER-encoded, so it's either PKCS12 or X.509.
|
||||||
if magic&0x0000FF00 == 0x0300 {
|
if magic&0x0000FF00 == 0x0300 {
|
||||||
// Probably X.509
|
// Probably X.509
|
||||||
return "DER", nil
|
return CertKeyFormatDER, nil
|
||||||
}
|
}
|
||||||
return "PKCS12", nil
|
return CertKeyFormatPKCS12, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return "", nil
|
return CertKeyFormatNONE, fmt.Errorf("unable to guess format for %v magic 0x%0x", filename, magic)
|
||||||
}
|
}
|
||||||
|
|
||||||
func readAsPEMEx2(filename string, format string, password string) ([]byte, error) {
|
func readAsPEMEx(filename string, format CertificateKeyFormat, password string) ([]byte, error) {
|
||||||
var pembuf bytes.Buffer
|
var pembuf bytes.Buffer
|
||||||
err := readAsPEMEx(filename, format, "", func(block *pem.Block, format string) error {
|
pembufFunc := func(block *pem.Block, format CertificateKeyFormat) error {
|
||||||
return pem.Encode(&pembuf, block)
|
return pem.Encode(&pembuf, block)
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("could not load client cert: %v", err)
|
|
||||||
}
|
}
|
||||||
return pembuf.Bytes(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func readAsPEMEx(filename string, format string, password string, callback func(*pem.Block, string) error) error {
|
|
||||||
rawFile, err := os.Open(filename)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("unable to open file: %s\n", err)
|
|
||||||
}
|
|
||||||
defer rawFile.Close()
|
|
||||||
passwordFunc := func(promet string) string {
|
passwordFunc := func(promet string) string {
|
||||||
return password
|
return password
|
||||||
}
|
}
|
||||||
|
|
||||||
reader := bufio.NewReaderSize(rawFile, 4)
|
rawFile, err := os.Open(filename)
|
||||||
format, err = formatForFile(reader, "", format)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to guess format for input stream")
|
return nil, fmt.Errorf("unable to open file: %s\n", err)
|
||||||
}
|
}
|
||||||
|
defer rawFile.Close()
|
||||||
|
|
||||||
return readCertsFromStream(reader, "", format, passwordFunc, callback)
|
err = readCertsFromStream(rawFile, "", format, passwordFunc, pembufFunc)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("could not read file: %s\n", err)
|
||||||
|
}
|
||||||
|
return pembuf.Bytes(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// // ReadAsPEMFromFiles will read PEM blocks from the given set of inputs. Input
|
// // ReadAsPEMFromFiles will read PEM blocks from the given set of inputs. Input
|
||||||
|
|
@ -287,26 +236,26 @@ func readAsPEMEx(filename string, format string, password string, callback func(
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
|
|
||||||
// ReadAsPEM will read PEM blocks from the given set of inputs. Input data may
|
//// ReadAsPEM will read PEM blocks from the given set of inputs. Input data may
|
||||||
// be in plain-text PEM files, DER-encoded certificates or PKCS7 envelopes, or
|
//// be in plain-text PEM files, DER-encoded certificates or PKCS7 envelopes, or
|
||||||
// PKCS12/JCEKS keystores. All inputs will be converted to PEM blocks and
|
//// PKCS12/JCEKS keystores. All inputs will be converted to PEM blocks and
|
||||||
// passed to the callback.
|
//// passed to the callback.
|
||||||
func ReadAsPEM(readers []io.Reader, format string, password func(string) string, callback func(*pem.Block, string) error) error {
|
//func ReadAsPEM(readers []io.Reader, format string, password func(string) string, callback func(*pem.Block, string) error) error {
|
||||||
errs := []error{}
|
// errs := []error{}
|
||||||
for _, r := range readers {
|
// for _, r := range readers {
|
||||||
reader := bufio.NewReaderSize(r, 4)
|
// reader := bufio.NewReaderSize(r, 4)
|
||||||
format, err := formatForFile(reader, "", format)
|
// format, err := formatForFile(reader, "", format)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return fmt.Errorf("unable to guess format for input stream")
|
// return fmt.Errorf("unable to guess format for input stream")
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
err = readCertsFromStream(reader, "", format, password, callback)
|
// err = readCertsFromStream(reader, "", format, password, callback)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
errs = append(errs, err)
|
// errs = append(errs, err)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
return errorFromErrors(errs)
|
// return errorFromErrors(errs)
|
||||||
}
|
//}
|
||||||
|
|
||||||
//// ReadAsX509FromFiles will read X.509 certificates from the given set of
|
//// ReadAsX509FromFiles will read X.509 certificates from the given set of
|
||||||
//// inputs. Input data may be in plain-text PEM files, DER-encoded certificates
|
//// inputs. Input data may be in plain-text PEM files, DER-encoded certificates
|
||||||
|
|
@ -380,15 +329,14 @@ func ReadAsPEM(readers []io.Reader, format string, password func(string) string,
|
||||||
//}
|
//}
|
||||||
|
|
||||||
// readCertsFromStream takes some input and converts it to PEM blocks.
|
// readCertsFromStream takes some input and converts it to PEM blocks.
|
||||||
func readCertsFromStream(reader io.Reader, filename string, format string, password func(string) string, callback func(*pem.Block, string) error) error {
|
func readCertsFromStream(reader io.Reader, filename string, format CertificateKeyFormat, password func(string) string, callback func(*pem.Block, CertificateKeyFormat) error) error {
|
||||||
headers := map[string]string{}
|
headers := map[string]string{}
|
||||||
if filename != "" && filename != os.Stdin.Name() {
|
if filename != "" && filename != os.Stdin.Name() {
|
||||||
headers[fileHeader] = filename
|
headers[fileHeader] = filename
|
||||||
}
|
}
|
||||||
|
|
||||||
format = strings.TrimSpace(format)
|
|
||||||
switch format {
|
switch format {
|
||||||
case "PEM":
|
case CertKeyFormatPEM:
|
||||||
scanner := pemScanner(reader)
|
scanner := pemScanner(reader)
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
block, _ := pem.Decode(scanner.Bytes())
|
block, _ := pem.Decode(scanner.Bytes())
|
||||||
|
|
@ -399,7 +347,7 @@ func readCertsFromStream(reader io.Reader, filename string, format string, passw
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
case "DER":
|
case CertKeyFormatDER:
|
||||||
data, err := ioutil.ReadAll(reader)
|
data, err := ioutil.ReadAll(reader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to read input: %s\n", err)
|
return fmt.Errorf("unable to read input: %s\n", err)
|
||||||
|
|
@ -407,6 +355,7 @@ func readCertsFromStream(reader io.Reader, filename string, format string, passw
|
||||||
x509Certs, err0 := x509.ParseCertificates(data)
|
x509Certs, err0 := x509.ParseCertificates(data)
|
||||||
if err0 == nil {
|
if err0 == nil {
|
||||||
for _, cert := range x509Certs {
|
for _, cert := range x509Certs {
|
||||||
|
fmt.Printf("cert cn: %v\n", cert.Issuer.CommonName)
|
||||||
err := callback(encodeX509ToPEM(cert, headers), format)
|
err := callback(encodeX509ToPEM(cert, headers), format)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
@ -425,7 +374,7 @@ func readCertsFromStream(reader io.Reader, filename string, format string, passw
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return fmt.Errorf("unable to parse certificates from DER data\n* X.509 parser gave: %s\n* PKCS7 parser gave: %s\n", err0, err1)
|
return fmt.Errorf("unable to parse certificates from DER data\n* X.509 parser gave: %s\n* PKCS7 parser gave: %s\n", err0, err1)
|
||||||
case "PKCS12":
|
case CertKeyFormatPKCS12:
|
||||||
data, err := ioutil.ReadAll(reader)
|
data, err := ioutil.ReadAll(reader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to read input: %s\n", err)
|
return fmt.Errorf("unable to read input: %s\n", err)
|
||||||
|
|
@ -442,7 +391,7 @@ func readCertsFromStream(reader io.Reader, filename string, format string, passw
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
case "JCEKS":
|
case CertKeyFormatJCEKS:
|
||||||
keyStore, err := jceks.LoadFromReader(reader, []byte(password("")))
|
keyStore, err := jceks.LoadFromReader(reader, []byte(password("")))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to parse keystore: %s\n", err)
|
return fmt.Errorf("unable to parse keystore: %s\n", err)
|
||||||
|
|
@ -534,48 +483,47 @@ func keyToPem(key crypto.PrivateKey, headers map[string]string) (*pem.Block, err
|
||||||
return nil, fmt.Errorf("unknown key type: %s\n", reflect.TypeOf(key))
|
return nil, fmt.Errorf("unknown key type: %s\n", reflect.TypeOf(key))
|
||||||
}
|
}
|
||||||
|
|
||||||
// formatForFile returns the file format (either from flags or
|
//// formatForFile returns the file format (either from flags or
|
||||||
// based on file extension).
|
//// based on file extension).
|
||||||
func formatForFile(file *bufio.Reader, filename, format string) (string, error) {
|
//func formatForFile(file *bufio.Reader, filename, format string) (string, error) {
|
||||||
// First, honor --format flag we got from user
|
// // First, honor --format flag we got from user
|
||||||
if format != "" {
|
// if format != "" {
|
||||||
return format, nil
|
// return format, nil
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
// Second, attempt to guess based on extension
|
// // Second, attempt to guess based on extension
|
||||||
guess, ok := fileExtToFormat[strings.ToLower(filepath.Ext(filename))]
|
// guess, ok := fileExtToFormat[strings.ToLower(filepath.Ext(filename))]
|
||||||
if ok {
|
// if ok {
|
||||||
return guess, nil
|
// return string(guess), nil
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
// Third, attempt to guess based on first 4 bytes of input
|
// // Third, attempt to guess based on first 4 bytes of input
|
||||||
data, err := file.Peek(4)
|
// data, err := file.Peek(4)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return "", fmt.Errorf("unable to read file: %s\n", err)
|
// return "", fmt.Errorf("unable to read file: %s\n", err)
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
// Heuristics for guessing -- best effort.
|
// // Heuristics for guessing -- best effort.
|
||||||
magic := binary.BigEndian.Uint32(data)
|
// magic := binary.BigEndian.Uint32(data)
|
||||||
if magic == 0xCECECECE || magic == 0xFEEDFEED {
|
// if magic == 0xCECECECE || magic == 0xFEEDFEED {
|
||||||
// JCEKS/JKS files always start with this prefix
|
// // JCEKS/JKS files always start with this prefix
|
||||||
return "JCEKS", nil
|
// return "JCEKS", nil
|
||||||
}
|
// }
|
||||||
if magic == 0x2D2D2D2D || magic == 0x434f4e4e {
|
// if magic == 0x2D2D2D2D || magic == 0x434f4e4e {
|
||||||
// Starts with '----' or 'CONN' (what s_client prints...)
|
// // Starts with '----' or 'CONN' (what s_client prints...)
|
||||||
// TODO start with 'Certificate'
|
// return "PEM", nil
|
||||||
return "PEM", nil
|
// }
|
||||||
}
|
// if magic&0xFFFF0000 == 0x30820000 {
|
||||||
if magic&0xFFFF0000 == 0x30820000 {
|
// // Looks like the input is DER-encoded, so it's either PKCS12 or X.509.
|
||||||
// Looks like the input is DER-encoded, so it's either PKCS12 or X.509.
|
// if magic&0x0000FF00 == 0x0300 {
|
||||||
if magic&0x0000FF00 == 0x0300 {
|
// // Probably X.509
|
||||||
// Probably X.509
|
// return "DER", nil
|
||||||
return "DER", nil
|
// }
|
||||||
}
|
// return "PKCS12", nil
|
||||||
return "PKCS12", nil
|
// }
|
||||||
}
|
//
|
||||||
|
// return "", fmt.Errorf("unable to guess file format")
|
||||||
return "", fmt.Errorf("unable to guess file format")
|
//}
|
||||||
}
|
|
||||||
|
|
||||||
// pemScanner will return a bufio.Scanner that splits the input
|
// pemScanner will return a bufio.Scanner that splits the input
|
||||||
// from the given reader into PEM blocks.
|
// from the given reader into PEM blocks.
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,64 @@
|
||||||
|
package lib
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestClientTLSConfig(t *testing.T) {
|
||||||
|
derfmt := CertKeyFormatDER
|
||||||
|
pemfmt := CertKeyFormatPEM
|
||||||
|
pfxfmt := CertKeyFormatPKCS12
|
||||||
|
testTLSConfig(t, false, "tls/ca.crt", pemfmt, "tls/client.crt", pemfmt, "tls/client.key", pemfmt, "")
|
||||||
|
testTLSConfig(t, false, "tls/ca.crt", pemfmt, "tls/client.der", derfmt, "tls/client.key", pemfmt, "")
|
||||||
|
testTLSConfig(t, false, "tls/ca.crt", pemfmt, "tls/client.pfx", pfxfmt, "tls/client.key", pemfmt, "")
|
||||||
|
testTLSConfig(t, false, "tls/ca.crt", pemfmt, "tls/client_pass.pfx", pfxfmt, "", pemfmt, "pfxpassword")
|
||||||
|
testTLSConfig(t, false, "tls/ca.der", derfmt, "tls/client.pfx", pfxfmt, "", pemfmt, "")
|
||||||
|
//testTLSConfig(t, false, "tls/ca.crt", pemfmt, "tls/client.crt", pemfmt, "tls/client.key.pass", pemfmt, "123456") // not support
|
||||||
|
//testTLSConfig(t, false, "tls/ca.crt", pemfmt, "tls/client_pass.pfx", pfxfmt, "", pemfmt, "invalidpwd") // invalid
|
||||||
|
//testTLSConfig(t, false, "tls/ca.crt", pemfmt, "tls/client.der", derfmt, "tls/client.key.der", derfmt, "") key can not be der
|
||||||
|
}
|
||||||
|
|
||||||
|
func testTLSConfig(
|
||||||
|
t *testing.T,
|
||||||
|
insecure bool,
|
||||||
|
cacert string,
|
||||||
|
cacertFormat CertificateKeyFormat,
|
||||||
|
cert string,
|
||||||
|
certFormat CertificateKeyFormat,
|
||||||
|
key string,
|
||||||
|
keyFormat CertificateKeyFormat,
|
||||||
|
pass string,
|
||||||
|
) {
|
||||||
|
tlsConf, err := ClientTLSConfigV2(insecure, cacert, cacertFormat, cert, certFormat, key, keyFormat, pass)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Failed to create TLS config err: %v", err)
|
||||||
|
}
|
||||||
|
if tlsConf == nil || tlsConf.Certificates == nil || tlsConf.RootCAs == nil {
|
||||||
|
t.Fatal("Failed to create TLS config tlsConf is nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGuessFormat(t *testing.T) {
|
||||||
|
guessFormat(t, "tls/client.crt", CertKeyFormatPEM)
|
||||||
|
guessFormat(t, "tls/client.cer", CertKeyFormatPEM)
|
||||||
|
guessFormat(t, "tls/client.key", CertKeyFormatPEM)
|
||||||
|
guessFormat(t, "tls/client.pfx", CertKeyFormatPKCS12)
|
||||||
|
guessFormat(t, "tls/client.der", CertKeyFormatDER)
|
||||||
|
forceFormat(t, "tls/client.guess", CertKeyFormatPEM, CertKeyFormatPEM)
|
||||||
|
}
|
||||||
|
|
||||||
|
func guessFormat(t *testing.T, filename string, formatExpected CertificateKeyFormat) {
|
||||||
|
forceFormat(t, filename, formatExpected, CertKeyFormatNONE)
|
||||||
|
}
|
||||||
|
|
||||||
|
func forceFormat(t *testing.T, filename string, formatExpected, formatForce CertificateKeyFormat) {
|
||||||
|
guessFormat, err := GuessFormatForFile(filename, formatForce)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to guess file err: %v", err)
|
||||||
|
}
|
||||||
|
if guessFormat != formatExpected {
|
||||||
|
t.Fatalf("failed to guess file %v format: %v expected: %v", filename, guessFormat, formatExpected)
|
||||||
|
}
|
||||||
|
t.Logf("format %v filename %v", guessFormat, filename)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
-----BEGIN X509 CRL-----
|
||||||
|
MIICfDBmAgEBMA0GCSqGSIb3DQEBCwUAMA0xCzAJBgNVBAMTAmNhFw0yMzEwMjQy
|
||||||
|
MzM5MThaFw0zNTA0MjQyMzM5MTZaMACgIzAhMB8GA1UdIwQYMBaAFAoT7NARRdDN
|
||||||
|
KQdlVkLUqtOsbJ54MA0GCSqGSIb3DQEBCwUAA4ICAQAdG+TDH5K5Y8xdB+kw9iIW
|
||||||
|
6icXq47ilbI/TRJbAq9BrmvPZXUI630fXojNijDgRqoSkgtbI+0wQuMqBFLJ0+VK
|
||||||
|
La4WTucsoYOQz89EJikB6z3m3BFNrubsxLjvNuW3i+ebi3ydH4VE2P7QgRjrW10K
|
||||||
|
M69pozzYM7CzNkQFmmXUcjcg/EPu4UiN2VQK6WXTTDBae1nGsAiZnsLyHNuFiK/G
|
||||||
|
9vVtoCDNc26GGaRb33Rh/1hS7hXqUCBQb1EdTNunZzVhAC9JfPdAKWlW35NWyrMz
|
||||||
|
/llYq3RMvouALXpOtRudi2G+ULto9iZdPGH9WiiVWpYx+Mdl1ab/yf/OzmsU8c1L
|
||||||
|
GHuh6Lx2Ed2Bz2y58Xk8di5IbER9GyVIecP3NbnL/Xrf0SKyw5WH/BTU66cwZgb6
|
||||||
|
aUPjqm+U3TUrNXGnh2FKy77CVUTnQV75GU1V+aFsmyplQUOjIHpTP+sAad88tIsg
|
||||||
|
AMDcezxBVydZV6Zfl+52pGR2aByd8FYZi27Y0ggh8CyMlrmYTKYRP10RbIHwcaKN
|
||||||
|
bH6CpxGvQDGXRvn6D7BY9qEVt1v2oQzIW11Gm6ldlWDYzLUG0YaID4RrJ3KP2wfX
|
||||||
|
0fbpbA35kBL+coZ8iLsH79qR8p90IYdhM4QNwfWfptwPcxxW4y5AfNgFD7hao6Wg
|
||||||
|
N1Hgooy5gkyxxwNUBlRXOg==
|
||||||
|
-----END X509 CRL-----
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIE2jCCAsKgAwIBAgIBATANBgkqhkiG9w0BAQsFADANMQswCQYDVQQDEwJjYTAe
|
||||||
|
Fw0yMzEwMjQyMzI5MThaFw0zNTA0MjQyMzM5MTZaMA0xCzAJBgNVBAMTAmNhMIIC
|
||||||
|
IjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAm+lCc8AxpzKpx65+fJIb/kX+
|
||||||
|
2wmRKjwZ107lsJRhKlEGZEyN6ncgIoDhsaZKBqcBtE8C4QqxWsocKLlb0irP1rnP
|
||||||
|
nfvUxglA0JFnHElq6KqfsW0aXcNe4DUU9iS2p69uvG/1aAEyUH5DMP0EpncJCLKp
|
||||||
|
1tw7lehQdNNFUtOdiMpfo88iiP+ECHdPEz3ZRmy9rjzXvWwd72AbH0x2/n7BE3SI
|
||||||
|
Q4njXDzFt1DZo/d2WssV1/Lghop5vQqeuUQS905Oc+VtKZ+OB52bTrqWsjvc+m8b
|
||||||
|
/bIUDTsKbR2Gm+/cTjLsjN5GgjAt0kVCS+N1iXSuvlJ/PfeQadk3XugPq20IWdF+
|
||||||
|
VlcWe45qrrEjmpBaqrHOKW1DzNjW2yRNmXTz7R3IncnzdFc6pGbpTLtHQ+qnWJ4c
|
||||||
|
5xCw7SOHdVWFgTBTWd/NMIbDQRwNWcJheFQKTGKwaEJ2uP/s7PNJkcyPH1LNzgfv
|
||||||
|
MH93zbSw1KNyO36Vslc4cd/lrgtY+b/oMsr49dOn52iNKcJQospcgRJR3S2vkdKx
|
||||||
|
6i+SFyHSTjP35W04eDRLvK6JNcs3S6yrnyc5bAasvk1gOaosru4/ffEWxXNtQxmi
|
||||||
|
4FiGUpEpzdCySy3rmnrvEuos269jC79ecS80QzEi825BcMtgStjo0sFfddLiZhx+
|
||||||
|
C0wMPv4e95M8YI1cc08CAwEAAaNFMEMwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB
|
||||||
|
/wQIMAYBAf8CAQAwHQYDVR0OBBYEFAoT7NARRdDNKQdlVkLUqtOsbJ54MA0GCSqG
|
||||||
|
SIb3DQEBCwUAA4ICAQBMFWBTyqLqK3ZMOXDupvyMGkjbGP3G4IbVd3e5gjya0qJ9
|
||||||
|
w7HhaUT+W/WjfvZ/AjMp3oweSqa1v2hpRQ9nh7odxRuOtOqiE85TCQDBmxyILWN4
|
||||||
|
uDWmUFMD5P0rOxwICLLaPy1TCFU/9PlYfO6OT0gj4FNtwK0Z2P7vl920WOpPaKfk
|
||||||
|
caTH9c1ZovZKCDgrJxWFk+XJdLQX5xTMPZdjPwZxvZnPp1RU2ZyUJKb5uBC6slMU
|
||||||
|
fPMpmYwd7kt03IyqMepqDRYFI79Va9d6J+E3+yeCbvsgVaZhKX1crHDK2MqkV+TG
|
||||||
|
E1q+r3VpxCD4efqWaUJDHE9YSbDG8pCT6yM+H4hooSJfTgTKS6Ip/PhEtaM5D02j
|
||||||
|
vnLwQkf+kB96bJ6ks5RolIsPgH9Y7lZ95sz4xoBT906AjemW+Z76wiMovrOeqa7g
|
||||||
|
eXy8sSQIxAVhg+oQOS9z2ryt/H/g3AJnMdpcRz+/yd0hFRvFiIY3oUwaaAprcLD/
|
||||||
|
a3X5+YKv1LFB9UohigroCofh0RtDXSX83cuP472Ant50qXk7D3WhdLzHLc1hgpPx
|
||||||
|
5jedrwzBh5VMW/fqhjqz2kCvS50ed+t83/kO9VGwyviiyipmw0VebDp3nCKmD1cx
|
||||||
|
VqL063NkQC83ijAG+GdeWYydqAqPikxcJnWunfbLFcr73lHjjLA64d+CE+rZOQ==
|
||||||
|
-----END CERTIFICATE-----
|
||||||
Binary file not shown.
|
|
@ -0,0 +1,51 @@
|
||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIIJKQIBAAKCAgEAm+lCc8AxpzKpx65+fJIb/kX+2wmRKjwZ107lsJRhKlEGZEyN
|
||||||
|
6ncgIoDhsaZKBqcBtE8C4QqxWsocKLlb0irP1rnPnfvUxglA0JFnHElq6KqfsW0a
|
||||||
|
XcNe4DUU9iS2p69uvG/1aAEyUH5DMP0EpncJCLKp1tw7lehQdNNFUtOdiMpfo88i
|
||||||
|
iP+ECHdPEz3ZRmy9rjzXvWwd72AbH0x2/n7BE3SIQ4njXDzFt1DZo/d2WssV1/Lg
|
||||||
|
hop5vQqeuUQS905Oc+VtKZ+OB52bTrqWsjvc+m8b/bIUDTsKbR2Gm+/cTjLsjN5G
|
||||||
|
gjAt0kVCS+N1iXSuvlJ/PfeQadk3XugPq20IWdF+VlcWe45qrrEjmpBaqrHOKW1D
|
||||||
|
zNjW2yRNmXTz7R3IncnzdFc6pGbpTLtHQ+qnWJ4c5xCw7SOHdVWFgTBTWd/NMIbD
|
||||||
|
QRwNWcJheFQKTGKwaEJ2uP/s7PNJkcyPH1LNzgfvMH93zbSw1KNyO36Vslc4cd/l
|
||||||
|
rgtY+b/oMsr49dOn52iNKcJQospcgRJR3S2vkdKx6i+SFyHSTjP35W04eDRLvK6J
|
||||||
|
Ncs3S6yrnyc5bAasvk1gOaosru4/ffEWxXNtQxmi4FiGUpEpzdCySy3rmnrvEuos
|
||||||
|
269jC79ecS80QzEi825BcMtgStjo0sFfddLiZhx+C0wMPv4e95M8YI1cc08CAwEA
|
||||||
|
AQKCAgEAhaHMn0GgTVqTQt9A8qyY6bw80KjGj5ir3Wt2W38SOR7xh45GJSytkmU9
|
||||||
|
DPMmh8UlJNKD+TcdBGAu+ojFNsITGkxws0xh9st/jkTSR+B1ja6Q6ZZF/w+xhiJ5
|
||||||
|
MPAOznMDSuf7Q4WjBnLyTE7RaYylZZsdD1f8imRwcXGT/YX7hH9QsiqbwyiellMM
|
||||||
|
p8VfMYmKmojzsRu2HLIXDSCQ7VjfTDmZganyAeDk5laZ9HvqKa/frRQzdZ3C8lDj
|
||||||
|
8o9yYh3wCE4g3ogvSD/CGhy7hVDh+pS5PR0hKqXsLdIcyhMwlKX5MlRhwrxgydUr
|
||||||
|
Gbh/ya0FCYPUI9zJHrBbUTE+HQR7Hopnv6ygGdUNm8Sb9ckfpDEOTnk2SHzp0vb9
|
||||||
|
6DTFL4q32ErZqq2B4FBgm8V7boH9XPEfpQokMqPlLXfbJqraGEclwG8V52AuUyrj
|
||||||
|
qaECj8KXlti/QSesr9IhDj18Xevyk3/FUSWmdaEZEQQ3vStU6V/TaJP++Nd5SE42
|
||||||
|
FY8Nb6+ze1Cmqgcz2ACIVKaFkudJMd/g58SNAGaY94NYeJ+V/3gIGxLJP9U0pw3L
|
||||||
|
i35BM3q8/MGkpkUQHerQC2CWdwILVElmEKYZ9DJ96VJzJIPGTj4jxMvWCcnOCyNE
|
||||||
|
NmUTFst//VYsvdnMuhEk3U1r1rc7Q9Cuqw1frQdJoVFLJVOpxOECggEBAMzcxroe
|
||||||
|
S0LvWDmRekqKyl8kYmd3olqqHNmd6opoY9TxIG1BHYHSbFVEc1falrLq7d1xvjlq
|
||||||
|
7EYR7Cb8Ccir7XrMfWRVvG7j/HUMTRZNJAQZBcG/qNkO7i3nLUhZ0NVxaKBPWfYE
|
||||||
|
txQ94rNmdpDMa9vqzRPlt2XlQ1j6eLsBqE+8/soVJrMS3DpQ3hcr/5w9WuXNYVLL
|
||||||
|
fTsL0Fs7Vn1H51gDiOFNRaVXWTzulyIjDlBtGRN0gbxPUy2Tj/s3kzOsR+uSlZcP
|
||||||
|
5h97VO8W7vBnA+AA1+thLR+o2gApxIRVHipTter1cQkwlm1SQSHmg27KqbN+oypQ
|
||||||
|
bKmvHOc2ME3cVDUCggEBAMLUYEApudCLB6GzcGfXJNhikwPz73yms2L7hccZorJ8
|
||||||
|
XSNM8EI8bETBgXBMX6TOFiMbPoaxQ3U0RGogivl4Vwq4Sw6jTY73JQDPROx896Ld
|
||||||
|
WAmTA6avgv8h0j9vD6HWGar2FCPNa4Gg5H8cAXACiBr0pPayJ7pQuw2OPZWq2mOw
|
||||||
|
9fsVwn/keMr/tYH2/YoGtWX2PL8mI4mm1c250vO83uSGGKml80EI7R7XXg5ToNWC
|
||||||
|
raxATgZfbqARYt1hhb0lO+kNrQNekZNzm/jK/9IPIAAmrK16aAgGqelIbYzggzCG
|
||||||
|
UUztJlIwfT+kI4qcyS2FqmGVyPMbm5vipNzcB4c9EfMCggEAYuTtFinLoStThq7g
|
||||||
|
vx1S5iz1SAdrm6LlPHRMJbaRAtnIEpXNfb8rxtm9aJrABuz8GNtwvd0M5CKAwq0G
|
||||||
|
uBWvFYmjuozc4xcx5vsiN3LTwRqnOcmg4++eMRCZPoUFGBSgMks8HVRXYPEjAAGl
|
||||||
|
mO7l3orxpvpM12aeZVS8dWIucxfEU590SBwBrjEdlUgLI8xGlgrYQZS0Bo4EbhYu
|
||||||
|
AVp1pnpGWKTpyxBops5yrOsJXO/dnBOxEUul1qmWZuqEJ/yx11my1vK431e1P5nt
|
||||||
|
jKXeLAOcOCd4FgF4A34mPM+uOTah6iPEBnCrHWkIwim6JwC0fU7Ty3h5jExZgpAZ
|
||||||
|
L2z+RQKCAQEAhZeusBBsc00B3KT37Jwfjah5+nnnu2drFfI2FwHDB/QywSPekuxv
|
||||||
|
qO2u3dvgsVcG4uephh5CjTlbuBG8ebdEp/sarFzZr7BT1SxKrIY8H5b66QW/uSob
|
||||||
|
/umoCwsSgvwV+Z5mzO3sS6SRSX9glPeHcERUYTxj9WOp/2+LVvcibL1IzfRru9pj
|
||||||
|
4X5ZbVZ5H43eEJ45pTB3qcmWTUygE7VsePJiMuGx3ORMA5vVyKkbXYwPnk8xsTj6
|
||||||
|
2BNT4U0fsUS4weM4wVi1JZBeYMiBhf4NCU17ljCa6PX4yBd71t+T1VAkq0Tpw+2v
|
||||||
|
1FWucTt0zxwaanOUqO5DUy6jsTXGi7sadQKCAQBc5Npv7lUb1fYqS7XJfbRn0594
|
||||||
|
OOJDRs6PlSygDEmialsqojtUXHVtjlKGRg96MfZt1dRK7op2AiAr9FSt1Y1+RKLe
|
||||||
|
gkVhV/N8cKG7nS66NOudGqIr8uAhphkIguaEwArZjxsTCcZxY4r31mHs1xXoB84Q
|
||||||
|
XoqtJQ0JLnH3p/KSC0B5EsYJNs9vyjSYnqLKzVxw99kxbSMIdjKsIm/UCRZjHSEM
|
||||||
|
I0fYAxYd93tot440W1u8lpYhqpfjB4RJ4I/AIkckGW9Ja0w+AZa7LCHO5ZXcD2Fh
|
||||||
|
3DyltARwQcWAQ5BOx8pBjcTIFkYgJyqdeDuIrqjclVn5znYdoolVAH/wr9qm
|
||||||
|
-----END RSA PRIVATE KEY-----
|
||||||
|
|
@ -0,0 +1,101 @@
|
||||||
|
Certificate:
|
||||||
|
Data:
|
||||||
|
Version: 3 (0x2)
|
||||||
|
Serial Number:
|
||||||
|
1c:c0:06:ac:3b:23:e6:29:6a:a1:79:67:5e:e7:c1:98
|
||||||
|
Signature Algorithm: sha256WithRSAEncryption
|
||||||
|
Issuer: CN=ca
|
||||||
|
Validity
|
||||||
|
Not Before: Oct 24 23:29:18 2023 GMT
|
||||||
|
Not After : Oct 24 23:39:18 2033 GMT
|
||||||
|
Subject: CN=client
|
||||||
|
Subject Public Key Info:
|
||||||
|
Public Key Algorithm: rsaEncryption
|
||||||
|
Public-Key: (2048 bit)
|
||||||
|
Modulus:
|
||||||
|
00:d1:ec:d0:8f:11:4f:bb:52:15:ff:81:69:98:4d:
|
||||||
|
16:fa:3b:93:3b:cb:65:20:14:cb:92:b9:aa:07:fc:
|
||||||
|
0b:92:85:a8:ef:66:ff:e9:70:57:f8:b0:4f:cb:dc:
|
||||||
|
a4:18:b3:e6:ee:3e:2d:2a:e6:fe:7f:0d:8d:05:47:
|
||||||
|
b0:2b:b0:1d:6c:77:dd:1a:fb:f0:ac:a2:49:a4:6f:
|
||||||
|
77:ec:b6:f1:da:e6:3b:90:08:eb:2d:8a:be:4d:57:
|
||||||
|
ff:da:fa:c2:5c:a2:67:68:f3:4e:2f:cd:b1:20:09:
|
||||||
|
fa:7c:7f:62:cb:1b:98:90:1c:58:74:d5:27:68:a9:
|
||||||
|
98:20:39:e8:b1:53:55:7f:64:38:e5:68:ef:b3:2e:
|
||||||
|
51:e3:2e:2a:56:1e:93:c9:ff:16:9c:a0:46:b4:86:
|
||||||
|
b9:a5:f4:d8:7f:72:ec:15:7e:8a:98:59:ee:e7:76:
|
||||||
|
0f:57:85:3e:80:d2:79:0a:b3:15:4d:5e:38:c8:60:
|
||||||
|
3f:10:62:12:6c:a6:97:4a:da:93:44:93:8c:2f:8a:
|
||||||
|
dd:0a:26:41:fb:2b:80:dc:93:2b:18:99:56:27:21:
|
||||||
|
cf:24:df:21:0e:a9:a6:21:41:cd:d9:0b:19:62:4a:
|
||||||
|
03:b5:ad:a7:be:bd:1e:80:b5:da:e1:0e:e7:28:5d:
|
||||||
|
41:cf:f2:30:6e:6f:7f:7f:ac:11:5a:44:1d:87:87:
|
||||||
|
6f:cb
|
||||||
|
Exponent: 65537 (0x10001)
|
||||||
|
X509v3 extensions:
|
||||||
|
X509v3 Key Usage: critical
|
||||||
|
Digital Signature, Key Encipherment, Data Encipherment, Key Agreement
|
||||||
|
X509v3 Extended Key Usage:
|
||||||
|
TLS Web Server Authentication, TLS Web Client Authentication
|
||||||
|
X509v3 Subject Key Identifier:
|
||||||
|
86:F9:9A:9A:8E:0B:23:62:72:65:A0:BB:6A:03:4F:A6:AB:50:78:B3
|
||||||
|
X509v3 Authority Key Identifier:
|
||||||
|
keyid:0A:13:EC:D0:11:45:D0:CD:29:07:65:56:42:D4:AA:D3:AC:6C:9E:78
|
||||||
|
|
||||||
|
X509v3 Subject Alternative Name:
|
||||||
|
DNS:client.com
|
||||||
|
Signature Algorithm: sha256WithRSAEncryption
|
||||||
|
32:4b:c5:cb:ed:61:4f:f3:98:cc:4b:5d:3e:5e:73:ea:8d:0f:
|
||||||
|
20:3c:42:c9:c2:f0:4c:7b:a4:3a:e2:7c:60:ba:a0:41:66:c4:
|
||||||
|
62:4f:88:26:4e:9f:28:08:dc:28:67:2f:39:04:fc:9b:2d:74:
|
||||||
|
d6:57:2b:0f:05:5f:96:85:77:26:11:bd:39:1b:e1:30:7c:ec:
|
||||||
|
40:ea:45:2a:3d:d7:2d:95:c5:25:75:09:59:f9:99:0a:9e:81:
|
||||||
|
bd:2a:f6:87:e7:d4:c3:0f:cf:eb:19:dc:53:96:81:5b:bc:36:
|
||||||
|
94:8f:21:fb:8c:5f:13:b1:5e:28:2e:9b:6a:99:d6:3d:16:f8:
|
||||||
|
b7:96:77:24:99:af:7e:93:06:84:a1:45:fc:22:50:af:cb:9f:
|
||||||
|
34:02:92:4c:f4:98:66:ab:d8:27:e2:68:84:e4:cb:f9:af:90:
|
||||||
|
f2:b0:1f:ae:cc:70:a5:ff:bf:e9:1e:81:bb:d1:1b:5a:a7:fb:
|
||||||
|
50:f7:ab:ae:ff:0d:d9:69:c6:76:d6:15:2e:b9:0b:e5:d7:84:
|
||||||
|
5a:ae:95:01:d1:e1:cb:8d:b7:ee:58:34:65:89:7e:b2:2b:3b:
|
||||||
|
cf:ef:b7:78:93:28:19:6b:a6:58:40:18:8b:c1:4d:cc:f7:ef:
|
||||||
|
38:06:9a:52:e3:85:6a:ff:9b:09:09:36:f6:a2:d3:e0:c4:b6:
|
||||||
|
ca:79:90:49:a1:70:08:13:ca:b8:88:16:ad:c2:eb:5f:be:5b:
|
||||||
|
25:be:1b:56:7d:b9:78:63:66:41:9a:db:b9:4e:e2:5a:14:28:
|
||||||
|
1b:ee:cf:14:52:ed:ff:56:ff:9b:98:06:93:cb:b6:92:77:52:
|
||||||
|
81:eb:31:6d:3e:6d:23:d9:c3:ff:38:24:24:66:96:7b:58:dc:
|
||||||
|
70:a7:b2:f6:a3:f1:b7:f2:99:84:2a:28:65:ba:65:5f:dd:be:
|
||||||
|
04:09:78:e4:42:8b:54:2e:9c:29:16:7f:7f:b5:e9:f6:53:c5:
|
||||||
|
26:a0:f5:d9:17:4e:69:b6:ac:2f:73:36:cc:f0:09:37:af:03:
|
||||||
|
c3:21:5d:87:75:86:1a:72:a1:a0:07:90:34:1d:01:d8:05:37:
|
||||||
|
0a:4c:ac:0d:10:b5:85:71:59:b7:96:94:e4:7c:9f:d8:60:7d:
|
||||||
|
1e:28:24:58:c9:21:1d:f1:d6:29:f2:5f:25:c6:a4:10:47:11:
|
||||||
|
1a:7f:fb:a4:8e:bd:a9:49:1a:9c:8d:7d:2c:83:b3:0c:89:ca:
|
||||||
|
12:0c:ed:69:37:0f:d0:0b:a0:2c:1c:67:d0:63:3a:b6:8e:b8:
|
||||||
|
21:af:fb:b3:54:19:6d:3c:b6:e1:e2:a3:d5:4f:f8:56:65:4c:
|
||||||
|
d4:c2:13:9e:e7:31:91:c9:13:b1:f5:14:c8:70:db:7d:d1:cf:
|
||||||
|
de:46:bd:63:6c:f9:d6:99
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIEMjCCAhqgAwIBAgIQHMAGrDsj5ilqoXlnXufBmDANBgkqhkiG9w0BAQsFADAN
|
||||||
|
MQswCQYDVQQDEwJjYTAeFw0yMzEwMjQyMzI5MThaFw0zMzEwMjQyMzM5MThaMBEx
|
||||||
|
DzANBgNVBAMTBmNsaWVudDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
|
||||||
|
ANHs0I8RT7tSFf+BaZhNFvo7kzvLZSAUy5K5qgf8C5KFqO9m/+lwV/iwT8vcpBiz
|
||||||
|
5u4+LSrm/n8NjQVHsCuwHWx33Rr78KyiSaRvd+y28drmO5AI6y2Kvk1X/9r6wlyi
|
||||||
|
Z2jzTi/NsSAJ+nx/YssbmJAcWHTVJ2ipmCA56LFTVX9kOOVo77MuUeMuKlYek8n/
|
||||||
|
FpygRrSGuaX02H9y7BV+iphZ7ud2D1eFPoDSeQqzFU1eOMhgPxBiEmyml0rak0ST
|
||||||
|
jC+K3QomQfsrgNyTKxiZVichzyTfIQ6ppiFBzdkLGWJKA7Wtp769HoC12uEO5yhd
|
||||||
|
Qc/yMG5vf3+sEVpEHYeHb8sCAwEAAaOBiTCBhjAOBgNVHQ8BAf8EBAMCA7gwHQYD
|
||||||
|
VR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMB0GA1UdDgQWBBSG+ZqajgsjYnJl
|
||||||
|
oLtqA0+mq1B4szAfBgNVHSMEGDAWgBQKE+zQEUXQzSkHZVZC1KrTrGyeeDAVBgNV
|
||||||
|
HREEDjAMggpjbGllbnQuY29tMA0GCSqGSIb3DQEBCwUAA4ICAQAyS8XL7WFP85jM
|
||||||
|
S10+XnPqjQ8gPELJwvBMe6Q64nxguqBBZsRiT4gmTp8oCNwoZy85BPybLXTWVysP
|
||||||
|
BV+WhXcmEb05G+EwfOxA6kUqPdctlcUldQlZ+ZkKnoG9KvaH59TDD8/rGdxTloFb
|
||||||
|
vDaUjyH7jF8TsV4oLptqmdY9Fvi3lnckma9+kwaEoUX8IlCvy580ApJM9Jhmq9gn
|
||||||
|
4miE5Mv5r5DysB+uzHCl/7/pHoG70Rtap/tQ96uu/w3ZacZ21hUuuQvl14RarpUB
|
||||||
|
0eHLjbfuWDRliX6yKzvP77d4kygZa6ZYQBiLwU3M9+84BppS44Vq/5sJCTb2otPg
|
||||||
|
xLbKeZBJoXAIE8q4iBatwutfvlslvhtWfbl4Y2ZBmtu5TuJaFCgb7s8UUu3/Vv+b
|
||||||
|
mAaTy7aSd1KB6zFtPm0j2cP/OCQkZpZ7WNxwp7L2o/G38pmEKihlumVf3b4ECXjk
|
||||||
|
QotULpwpFn9/ten2U8UmoPXZF05ptqwvczbM8Ak3rwPDIV2HdYYacqGgB5A0HQHY
|
||||||
|
BTcKTKwNELWFcVm3lpTkfJ/YYH0eKCRYySEd8dYp8l8lxqQQRxEaf/ukjr2pSRqc
|
||||||
|
jX0sg7MMicoSDO1pNw/QC6AsHGfQYzq2jrghr/uzVBltPLbh4qPVT/hWZUzUwhOe
|
||||||
|
5zGRyROx9RTIcNt90c/eRr1jbPnWmQ==
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIEMjCCAhqgAwIBAgIQHMAGrDsj5ilqoXlnXufBmDANBgkqhkiG9w0BAQsFADAN
|
||||||
|
MQswCQYDVQQDEwJjYTAeFw0yMzEwMjQyMzI5MThaFw0zMzEwMjQyMzM5MThaMBEx
|
||||||
|
DzANBgNVBAMTBmNsaWVudDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
|
||||||
|
ANHs0I8RT7tSFf+BaZhNFvo7kzvLZSAUy5K5qgf8C5KFqO9m/+lwV/iwT8vcpBiz
|
||||||
|
5u4+LSrm/n8NjQVHsCuwHWx33Rr78KyiSaRvd+y28drmO5AI6y2Kvk1X/9r6wlyi
|
||||||
|
Z2jzTi/NsSAJ+nx/YssbmJAcWHTVJ2ipmCA56LFTVX9kOOVo77MuUeMuKlYek8n/
|
||||||
|
FpygRrSGuaX02H9y7BV+iphZ7ud2D1eFPoDSeQqzFU1eOMhgPxBiEmyml0rak0ST
|
||||||
|
jC+K3QomQfsrgNyTKxiZVichzyTfIQ6ppiFBzdkLGWJKA7Wtp769HoC12uEO5yhd
|
||||||
|
Qc/yMG5vf3+sEVpEHYeHb8sCAwEAAaOBiTCBhjAOBgNVHQ8BAf8EBAMCA7gwHQYD
|
||||||
|
VR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMB0GA1UdDgQWBBSG+ZqajgsjYnJl
|
||||||
|
oLtqA0+mq1B4szAfBgNVHSMEGDAWgBQKE+zQEUXQzSkHZVZC1KrTrGyeeDAVBgNV
|
||||||
|
HREEDjAMggpjbGllbnQuY29tMA0GCSqGSIb3DQEBCwUAA4ICAQAyS8XL7WFP85jM
|
||||||
|
S10+XnPqjQ8gPELJwvBMe6Q64nxguqBBZsRiT4gmTp8oCNwoZy85BPybLXTWVysP
|
||||||
|
BV+WhXcmEb05G+EwfOxA6kUqPdctlcUldQlZ+ZkKnoG9KvaH59TDD8/rGdxTloFb
|
||||||
|
vDaUjyH7jF8TsV4oLptqmdY9Fvi3lnckma9+kwaEoUX8IlCvy580ApJM9Jhmq9gn
|
||||||
|
4miE5Mv5r5DysB+uzHCl/7/pHoG70Rtap/tQ96uu/w3ZacZ21hUuuQvl14RarpUB
|
||||||
|
0eHLjbfuWDRliX6yKzvP77d4kygZa6ZYQBiLwU3M9+84BppS44Vq/5sJCTb2otPg
|
||||||
|
xLbKeZBJoXAIE8q4iBatwutfvlslvhtWfbl4Y2ZBmtu5TuJaFCgb7s8UUu3/Vv+b
|
||||||
|
mAaTy7aSd1KB6zFtPm0j2cP/OCQkZpZ7WNxwp7L2o/G38pmEKihlumVf3b4ECXjk
|
||||||
|
QotULpwpFn9/ten2U8UmoPXZF05ptqwvczbM8Ak3rwPDIV2HdYYacqGgB5A0HQHY
|
||||||
|
BTcKTKwNELWFcVm3lpTkfJ/YYH0eKCRYySEd8dYp8l8lxqQQRxEaf/ukjr2pSRqc
|
||||||
|
jX0sg7MMicoSDO1pNw/QC6AsHGfQYzq2jrghr/uzVBltPLbh4qPVT/hWZUzUwhOe
|
||||||
|
5zGRyROx9RTIcNt90c/eRr1jbPnWmQ==
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
-----BEGIN CERTIFICATE REQUEST-----
|
||||||
|
MIICfjCCAWYCAQAwETEPMA0GA1UEAxMGY2xpZW50MIIBIjANBgkqhkiG9w0BAQEF
|
||||||
|
AAOCAQ8AMIIBCgKCAQEA0ezQjxFPu1IV/4FpmE0W+juTO8tlIBTLkrmqB/wLkoWo
|
||||||
|
72b/6XBX+LBPy9ykGLPm7j4tKub+fw2NBUewK7AdbHfdGvvwrKJJpG937Lbx2uY7
|
||||||
|
kAjrLYq+TVf/2vrCXKJnaPNOL82xIAn6fH9iyxuYkBxYdNUnaKmYIDnosVNVf2Q4
|
||||||
|
5Wjvsy5R4y4qVh6Tyf8WnKBGtIa5pfTYf3LsFX6KmFnu53YPV4U+gNJ5CrMVTV44
|
||||||
|
yGA/EGISbKaXStqTRJOML4rdCiZB+yuA3JMrGJlWJyHPJN8hDqmmIUHN2QsZYkoD
|
||||||
|
ta2nvr0egLXa4Q7nKF1Bz/Iwbm9/f6wRWkQdh4dvywIDAQABoCgwJgYJKoZIhvcN
|
||||||
|
AQkOMRkwFzAVBgNVHREEDjAMggpjbGllbnQuY29tMA0GCSqGSIb3DQEBCwUAA4IB
|
||||||
|
AQCk6+YAX3TIhnqV8cUjt++viZrc/DFBAaDhD0NcmKE1SjPwd32UzDDXaunNwWQ8
|
||||||
|
htz0dP0x0qSWFQjrUkYbFmUVt4La5kbsNoNNGFJqtVaDbCRI5ye8pg2TUvLkADM2
|
||||||
|
daSKMwabNqSAgbW+w1kMk+v9F6A4TFb7Z8/DoRWtWmJS/uR3PkvGOy7skV26+f+t
|
||||||
|
FCty+DD/2NUe98chXPi2xu9aQld4ZLyWw5KDQqcyS4Gr1fOQQQWENqSM4T76yhuu
|
||||||
|
LAzpD7sKoqa7u5LsWVr6iQLIhKLU6BHxjZqV7SmGZranIZ0hqWfuRKs04dq/fTXK
|
||||||
|
GoVHc0Bd9JlPzp0faSgj55jg
|
||||||
|
-----END CERTIFICATE REQUEST-----
|
||||||
Binary file not shown.
|
|
@ -0,0 +1,101 @@
|
||||||
|
guessCertificate:
|
||||||
|
Data:
|
||||||
|
Version: 3 (0x2)
|
||||||
|
Serial Number:
|
||||||
|
1c:c0:06:ac:3b:23:e6:29:6a:a1:79:67:5e:e7:c1:98
|
||||||
|
Signature Algorithm: sha256WithRSAEncryption
|
||||||
|
Issuer: CN=ca
|
||||||
|
Validity
|
||||||
|
Not Before: Oct 24 23:29:18 2023 GMT
|
||||||
|
Not After : Oct 24 23:39:18 2033 GMT
|
||||||
|
Subject: CN=client
|
||||||
|
Subject Public Key Info:
|
||||||
|
Public Key Algorithm: rsaEncryption
|
||||||
|
Public-Key: (2048 bit)
|
||||||
|
Modulus:
|
||||||
|
00:d1:ec:d0:8f:11:4f:bb:52:15:ff:81:69:98:4d:
|
||||||
|
16:fa:3b:93:3b:cb:65:20:14:cb:92:b9:aa:07:fc:
|
||||||
|
0b:92:85:a8:ef:66:ff:e9:70:57:f8:b0:4f:cb:dc:
|
||||||
|
a4:18:b3:e6:ee:3e:2d:2a:e6:fe:7f:0d:8d:05:47:
|
||||||
|
b0:2b:b0:1d:6c:77:dd:1a:fb:f0:ac:a2:49:a4:6f:
|
||||||
|
77:ec:b6:f1:da:e6:3b:90:08:eb:2d:8a:be:4d:57:
|
||||||
|
ff:da:fa:c2:5c:a2:67:68:f3:4e:2f:cd:b1:20:09:
|
||||||
|
fa:7c:7f:62:cb:1b:98:90:1c:58:74:d5:27:68:a9:
|
||||||
|
98:20:39:e8:b1:53:55:7f:64:38:e5:68:ef:b3:2e:
|
||||||
|
51:e3:2e:2a:56:1e:93:c9:ff:16:9c:a0:46:b4:86:
|
||||||
|
b9:a5:f4:d8:7f:72:ec:15:7e:8a:98:59:ee:e7:76:
|
||||||
|
0f:57:85:3e:80:d2:79:0a:b3:15:4d:5e:38:c8:60:
|
||||||
|
3f:10:62:12:6c:a6:97:4a:da:93:44:93:8c:2f:8a:
|
||||||
|
dd:0a:26:41:fb:2b:80:dc:93:2b:18:99:56:27:21:
|
||||||
|
cf:24:df:21:0e:a9:a6:21:41:cd:d9:0b:19:62:4a:
|
||||||
|
03:b5:ad:a7:be:bd:1e:80:b5:da:e1:0e:e7:28:5d:
|
||||||
|
41:cf:f2:30:6e:6f:7f:7f:ac:11:5a:44:1d:87:87:
|
||||||
|
6f:cb
|
||||||
|
Exponent: 65537 (0x10001)
|
||||||
|
X509v3 extensions:
|
||||||
|
X509v3 Key Usage: critical
|
||||||
|
Digital Signature, Key Encipherment, Data Encipherment, Key Agreement
|
||||||
|
X509v3 Extended Key Usage:
|
||||||
|
TLS Web Server Authentication, TLS Web Client Authentication
|
||||||
|
X509v3 Subject Key Identifier:
|
||||||
|
86:F9:9A:9A:8E:0B:23:62:72:65:A0:BB:6A:03:4F:A6:AB:50:78:B3
|
||||||
|
X509v3 Authority Key Identifier:
|
||||||
|
keyid:0A:13:EC:D0:11:45:D0:CD:29:07:65:56:42:D4:AA:D3:AC:6C:9E:78
|
||||||
|
|
||||||
|
X509v3 Subject Alternative Name:
|
||||||
|
DNS:client.com
|
||||||
|
Signature Algorithm: sha256WithRSAEncryption
|
||||||
|
32:4b:c5:cb:ed:61:4f:f3:98:cc:4b:5d:3e:5e:73:ea:8d:0f:
|
||||||
|
20:3c:42:c9:c2:f0:4c:7b:a4:3a:e2:7c:60:ba:a0:41:66:c4:
|
||||||
|
62:4f:88:26:4e:9f:28:08:dc:28:67:2f:39:04:fc:9b:2d:74:
|
||||||
|
d6:57:2b:0f:05:5f:96:85:77:26:11:bd:39:1b:e1:30:7c:ec:
|
||||||
|
40:ea:45:2a:3d:d7:2d:95:c5:25:75:09:59:f9:99:0a:9e:81:
|
||||||
|
bd:2a:f6:87:e7:d4:c3:0f:cf:eb:19:dc:53:96:81:5b:bc:36:
|
||||||
|
94:8f:21:fb:8c:5f:13:b1:5e:28:2e:9b:6a:99:d6:3d:16:f8:
|
||||||
|
b7:96:77:24:99:af:7e:93:06:84:a1:45:fc:22:50:af:cb:9f:
|
||||||
|
34:02:92:4c:f4:98:66:ab:d8:27:e2:68:84:e4:cb:f9:af:90:
|
||||||
|
f2:b0:1f:ae:cc:70:a5:ff:bf:e9:1e:81:bb:d1:1b:5a:a7:fb:
|
||||||
|
50:f7:ab:ae:ff:0d:d9:69:c6:76:d6:15:2e:b9:0b:e5:d7:84:
|
||||||
|
5a:ae:95:01:d1:e1:cb:8d:b7:ee:58:34:65:89:7e:b2:2b:3b:
|
||||||
|
cf:ef:b7:78:93:28:19:6b:a6:58:40:18:8b:c1:4d:cc:f7:ef:
|
||||||
|
38:06:9a:52:e3:85:6a:ff:9b:09:09:36:f6:a2:d3:e0:c4:b6:
|
||||||
|
ca:79:90:49:a1:70:08:13:ca:b8:88:16:ad:c2:eb:5f:be:5b:
|
||||||
|
25:be:1b:56:7d:b9:78:63:66:41:9a:db:b9:4e:e2:5a:14:28:
|
||||||
|
1b:ee:cf:14:52:ed:ff:56:ff:9b:98:06:93:cb:b6:92:77:52:
|
||||||
|
81:eb:31:6d:3e:6d:23:d9:c3:ff:38:24:24:66:96:7b:58:dc:
|
||||||
|
70:a7:b2:f6:a3:f1:b7:f2:99:84:2a:28:65:ba:65:5f:dd:be:
|
||||||
|
04:09:78:e4:42:8b:54:2e:9c:29:16:7f:7f:b5:e9:f6:53:c5:
|
||||||
|
26:a0:f5:d9:17:4e:69:b6:ac:2f:73:36:cc:f0:09:37:af:03:
|
||||||
|
c3:21:5d:87:75:86:1a:72:a1:a0:07:90:34:1d:01:d8:05:37:
|
||||||
|
0a:4c:ac:0d:10:b5:85:71:59:b7:96:94:e4:7c:9f:d8:60:7d:
|
||||||
|
1e:28:24:58:c9:21:1d:f1:d6:29:f2:5f:25:c6:a4:10:47:11:
|
||||||
|
1a:7f:fb:a4:8e:bd:a9:49:1a:9c:8d:7d:2c:83:b3:0c:89:ca:
|
||||||
|
12:0c:ed:69:37:0f:d0:0b:a0:2c:1c:67:d0:63:3a:b6:8e:b8:
|
||||||
|
21:af:fb:b3:54:19:6d:3c:b6:e1:e2:a3:d5:4f:f8:56:65:4c:
|
||||||
|
d4:c2:13:9e:e7:31:91:c9:13:b1:f5:14:c8:70:db:7d:d1:cf:
|
||||||
|
de:46:bd:63:6c:f9:d6:99
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIEMjCCAhqgAwIBAgIQHMAGrDsj5ilqoXlnXufBmDANBgkqhkiG9w0BAQsFADAN
|
||||||
|
MQswCQYDVQQDEwJjYTAeFw0yMzEwMjQyMzI5MThaFw0zMzEwMjQyMzM5MThaMBEx
|
||||||
|
DzANBgNVBAMTBmNsaWVudDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
|
||||||
|
ANHs0I8RT7tSFf+BaZhNFvo7kzvLZSAUy5K5qgf8C5KFqO9m/+lwV/iwT8vcpBiz
|
||||||
|
5u4+LSrm/n8NjQVHsCuwHWx33Rr78KyiSaRvd+y28drmO5AI6y2Kvk1X/9r6wlyi
|
||||||
|
Z2jzTi/NsSAJ+nx/YssbmJAcWHTVJ2ipmCA56LFTVX9kOOVo77MuUeMuKlYek8n/
|
||||||
|
FpygRrSGuaX02H9y7BV+iphZ7ud2D1eFPoDSeQqzFU1eOMhgPxBiEmyml0rak0ST
|
||||||
|
jC+K3QomQfsrgNyTKxiZVichzyTfIQ6ppiFBzdkLGWJKA7Wtp769HoC12uEO5yhd
|
||||||
|
Qc/yMG5vf3+sEVpEHYeHb8sCAwEAAaOBiTCBhjAOBgNVHQ8BAf8EBAMCA7gwHQYD
|
||||||
|
VR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMB0GA1UdDgQWBBSG+ZqajgsjYnJl
|
||||||
|
oLtqA0+mq1B4szAfBgNVHSMEGDAWgBQKE+zQEUXQzSkHZVZC1KrTrGyeeDAVBgNV
|
||||||
|
HREEDjAMggpjbGllbnQuY29tMA0GCSqGSIb3DQEBCwUAA4ICAQAyS8XL7WFP85jM
|
||||||
|
S10+XnPqjQ8gPELJwvBMe6Q64nxguqBBZsRiT4gmTp8oCNwoZy85BPybLXTWVysP
|
||||||
|
BV+WhXcmEb05G+EwfOxA6kUqPdctlcUldQlZ+ZkKnoG9KvaH59TDD8/rGdxTloFb
|
||||||
|
vDaUjyH7jF8TsV4oLptqmdY9Fvi3lnckma9+kwaEoUX8IlCvy580ApJM9Jhmq9gn
|
||||||
|
4miE5Mv5r5DysB+uzHCl/7/pHoG70Rtap/tQ96uu/w3ZacZ21hUuuQvl14RarpUB
|
||||||
|
0eHLjbfuWDRliX6yKzvP77d4kygZa6ZYQBiLwU3M9+84BppS44Vq/5sJCTb2otPg
|
||||||
|
xLbKeZBJoXAIE8q4iBatwutfvlslvhtWfbl4Y2ZBmtu5TuJaFCgb7s8UUu3/Vv+b
|
||||||
|
mAaTy7aSd1KB6zFtPm0j2cP/OCQkZpZ7WNxwp7L2o/G38pmEKihlumVf3b4ECXjk
|
||||||
|
QotULpwpFn9/ten2U8UmoPXZF05ptqwvczbM8Ak3rwPDIV2HdYYacqGgB5A0HQHY
|
||||||
|
BTcKTKwNELWFcVm3lpTkfJ/YYH0eKCRYySEd8dYp8l8lxqQQRxEaf/ukjr2pSRqc
|
||||||
|
jX0sg7MMicoSDO1pNw/QC6AsHGfQYzq2jrghr/uzVBltPLbh4qPVT/hWZUzUwhOe
|
||||||
|
5zGRyROx9RTIcNt90c/eRr1jbPnWmQ==
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIIEowIBAAKCAQEA0ezQjxFPu1IV/4FpmE0W+juTO8tlIBTLkrmqB/wLkoWo72b/
|
||||||
|
6XBX+LBPy9ykGLPm7j4tKub+fw2NBUewK7AdbHfdGvvwrKJJpG937Lbx2uY7kAjr
|
||||||
|
LYq+TVf/2vrCXKJnaPNOL82xIAn6fH9iyxuYkBxYdNUnaKmYIDnosVNVf2Q45Wjv
|
||||||
|
sy5R4y4qVh6Tyf8WnKBGtIa5pfTYf3LsFX6KmFnu53YPV4U+gNJ5CrMVTV44yGA/
|
||||||
|
EGISbKaXStqTRJOML4rdCiZB+yuA3JMrGJlWJyHPJN8hDqmmIUHN2QsZYkoDta2n
|
||||||
|
vr0egLXa4Q7nKF1Bz/Iwbm9/f6wRWkQdh4dvywIDAQABAoIBABvzYhmKfok8dr1c
|
||||||
|
Z8jliseqowH1JPPOkQRqQB9sCcZqkYG+vxg/4xazsww7xoWbfoX+NVlfBEe6cCph
|
||||||
|
zy0h9+j3VLNBFFyIBzIjvV4BRdaVjRyyc03PCWOW8fQgKzzWStqIesKWqpzPd1CY
|
||||||
|
TXkppXiarZRwxRyEaELyMu9ZXyrk2XndGg5UoHx84YxmLnTLDoRqCzt4rhRPhMye
|
||||||
|
YLYSbmY+BOhwC41bZdMKEG+4now6qtzZD7FpXtTshbgTq1MTPYPIphe9ihQhVn1C
|
||||||
|
2WTR+5ICI/ZrZ4kzQqMCic+hyhL+MOYZc0jN+5NT5djaWA9LXJhzUOvrCApeWX5b
|
||||||
|
wRgzwPECgYEA3VDO/z2tZlCzjnPGly2yBl4O/0KcK1/YHMtapPdRG71bocJ/hTtu
|
||||||
|
usfEaonpuD102fTEgVVpUXUgtS9QYG0kHYpZXSc5IRhXFEBBTLCSMzEf40pXVy2J
|
||||||
|
dwYO5l+bEMQydIyCvaQRj+QM1ypYECARM/N2/1Ww7K9cMw/yHlMksmcCgYEA8tMD
|
||||||
|
yrBVthYbJK1eLmWwTbFg4eRz7XmGBc5nzWmKp3UP7cijkrGfi5KRNg50zfywbGUR
|
||||||
|
BFyINSKcCymjzG5y4HH3EAo/3adoranzrQLy4dTsVGV97rWuxQN1pwtB3WjdpmM+
|
||||||
|
8NgnaMli3PdPXmghdYu/J/c+BG0ytfWsjH7v4P0CgYAtw7gKL8bbkXSP0IEQYfKe
|
||||||
|
PnT7c9q3XWpjCeoEkt/CzLVWDdIwyslq9kQ3g61A2/R93Y+E7xSIM6A/1zjXt7nw
|
||||||
|
Idu415OItG/NUDwwj5Kr40ykw4qsDE6Qvj/2g26dWPTWBPhEHtlC1/WPyMHNE9R6
|
||||||
|
2a2RvzaGuvxl0rZObwL3oQKBgAIcp7nJktVEl/PXtiv9Im1qj4cnb4KvPeUrCGgW
|
||||||
|
9OfD8uGEjzelZ9fU7IJl2co42mf28RDypRShOm42bIBIraMaGqX/ENMis5xfEAl/
|
||||||
|
LxGbwnpxb4j195ErGIjdZjNAyDy8PD3oA1+78KovVHdjvHbDQmRcmCN9t6Uxf9Cx
|
||||||
|
AfEZAoGBAKXHTCGg6DpulYRKFeWgfVBAK/5SK5b/rgblDZAmN6KyMZTaFcQ+dx7f
|
||||||
|
oQCJFN2YgXuRthIAOTf6qZS31oBGB51g53QHK4e5rvkT6aLAPXOMhKeCDGWUFMNg
|
||||||
|
HboNbpcDlK81yb/TQEXcEvTngo4QEfePq/at7pN4+lbBok2wMyRB
|
||||||
|
-----END RSA PRIVATE KEY-----
|
||||||
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,18 @@
|
||||||
|
|
||||||
|
set -ex
|
||||||
|
|
||||||
|
# generate der and pkcs12 file
|
||||||
|
openssl x509 -outform der -in tls/ca.crt -out tls/ca.der
|
||||||
|
openssl x509 -outform der -in tls/client.crt -out tls/client.der
|
||||||
|
openssl pkcs12 -export \
|
||||||
|
-in tls/client.crt \
|
||||||
|
-inkey tls/client.key \
|
||||||
|
-certfile tls/ca.crt \
|
||||||
|
-out tls/client.pfx \
|
||||||
|
-password pass:
|
||||||
|
openssl pkcs12 -export \
|
||||||
|
-in tls/client.crt \
|
||||||
|
-inkey tls/client.key \
|
||||||
|
-certfile tls/ca.crt \
|
||||||
|
-out tls/client_pass.pfx \
|
||||||
|
-password pass:pfxpassword
|
||||||
Loading…
Reference in New Issue