diff --git a/go.mod b/go.mod index c520363..5dcad48 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( go.osspkg.com/ioutils v0.7.3 go.osspkg.com/random v0.5.0 go.osspkg.com/syncing v0.4.3 - golang.org/x/crypto v0.43.0 + golang.org/x/crypto v0.46.0 ) -require golang.org/x/sys v0.37.0 // indirect +require golang.org/x/sys v0.39.0 // indirect diff --git a/go.sum b/go.sum index 99b5d96..d7629f0 100644 --- a/go.sum +++ b/go.sum @@ -8,7 +8,7 @@ go.osspkg.com/random v0.5.0 h1:6x2CQ5Vb6PVyuGi6Ao3K6Pr2fzVviBPCEEJC5HQNSmg= go.osspkg.com/random v0.5.0/go.mod h1:lsg3FI87PQdjhVWIVo2GXyPBclipljUxjMlWqRl2cck= go.osspkg.com/syncing v0.4.3 h1:XioXG9zje1LNCsfQhNHkNPCQqPSJZHWTzM8Xig2zvAU= go.osspkg.com/syncing v0.4.3/go.mod h1:/LBmgCAHFW6nQgVDILpEuo6eRCFK1yyFeNbDs4eVNls= -golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04= -golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0= -golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ= -golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU= +golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0= +golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= +golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= diff --git a/pki/alg_ecdsa.go b/pki/alg_ecdsa.go index 8f06a1c..562b35f 100644 --- a/pki/alg_ecdsa.go +++ b/pki/alg_ecdsa.go @@ -53,17 +53,17 @@ func (*_ecdsa) IsValidPair(key crypto.Signer, cert x509.Certificate) bool { return reflect.DeepEqual(pk, ck) } -func (*_ecdsa) Generate(ct CertType) (crypto.Signer, error) { +func (*_ecdsa) Generate(alg x509.SignatureAlgorithm) (crypto.Signer, error) { var curve elliptic.Curve - switch ct { - case RootCaCert: + switch alg { + case x509.ECDSAWithSHA256: curve = elliptic.P256() - case InterCACert: + case x509.ECDSAWithSHA384: curve = elliptic.P384() - case ClientCert: - curve = elliptic.P256() + case x509.ECDSAWithSHA512: + curve = elliptic.P521() default: - return nil, fmt.Errorf("unknown certificate curve for '%s'", ct) + return nil, fmt.Errorf("unknown certificate curve for '%s'", alg.String()) } return ecdsa.GenerateKey(curve, rand.Reader) diff --git a/pki/alg_rsa.go b/pki/alg_rsa.go index 717aa43..93aa051 100644 --- a/pki/alg_rsa.go +++ b/pki/alg_rsa.go @@ -52,17 +52,16 @@ func (*_rsa) IsValidPair(key crypto.Signer, cert x509.Certificate) bool { return reflect.DeepEqual(pk, ck) } -func (*_rsa) Generate(ct CertType) (crypto.Signer, error) { +func (*_rsa) Generate(alg x509.SignatureAlgorithm) (crypto.Signer, error) { var bits int - switch ct { - case RootCaCert: + switch alg { + case x509.SHA512WithRSA, x509.SHA384WithRSA, + x509.SHA512WithRSAPSS, x509.SHA384WithRSAPSS: bits = 4096 - case InterCACert: + case x509.SHA256WithRSA: bits = 3072 - case ClientCert: - bits = 2048 default: - return nil, fmt.Errorf("unknown certificate bits for '%s'", ct) + return nil, fmt.Errorf("unknown certificate bits for '%s'", alg.String()) } return rsa.GenerateKey(rand.Reader, bits) diff --git a/pki/alg_type.go b/pki/alg_type.go index 643ea31..3a47e6d 100644 --- a/pki/alg_type.go +++ b/pki/alg_type.go @@ -24,8 +24,11 @@ func Register(k x509.SignatureAlgorithm, v Algorithm) { func init() { Register(x509.SHA256WithRSA, &_rsa{}) + Register(x509.SHA256WithRSAPSS, &_rsa{}) Register(x509.SHA384WithRSA, &_rsa{}) + Register(x509.SHA384WithRSAPSS, &_rsa{}) Register(x509.SHA512WithRSA, &_rsa{}) + Register(x509.SHA512WithRSAPSS, &_rsa{}) Register(x509.ECDSAWithSHA256, &_ecdsa{}) Register(x509.ECDSAWithSHA384, &_ecdsa{}) Register(x509.ECDSAWithSHA512, &_ecdsa{}) @@ -37,13 +40,5 @@ type Algorithm interface { IsRequest(cert x509.CertificateRequest) bool IsCertificate(cert x509.Certificate) bool IsValidPair(key crypto.Signer, cert x509.Certificate) bool - Generate(ct CertType) (crypto.Signer, error) + Generate(alg x509.SignatureAlgorithm) (crypto.Signer, error) } - -type CertType string - -const ( - RootCaCert CertType = "root_ca_cert" - InterCACert CertType = "intermediate_ca_cert" - ClientCert CertType = "client_cert" -) diff --git a/pki/common.go b/pki/common.go index 00736e7..9453c5f 100644 --- a/pki/common.go +++ b/pki/common.go @@ -10,10 +10,36 @@ import ( _ "crypto/sha1" _ "crypto/sha256" _ "crypto/sha512" + "encoding/asn1" - _ "golang.org/x/crypto/blake2b" _ "golang.org/x/crypto/blake2s" _ "golang.org/x/crypto/md4" _ "golang.org/x/crypto/ripemd160" _ "golang.org/x/crypto/sha3" ) + +type policyQualifierInfo struct { + PolicyQualifierID asn1.ObjectIdentifier + Qualifier string `asn1:"ia5"` +} +type policyInformation struct { + PolicyIdentifier asn1.ObjectIdentifier + PolicyQualifiers []policyQualifierInfo `asn1:"optional"` +} + +func marshalPolicyCPSUrl(urls ...string) []byte { + info := policyInformation{ + PolicyIdentifier: asn1.ObjectIdentifier{2, 23, 140, 1, 2, 1}, + PolicyQualifiers: make([]policyQualifierInfo, 0, len(urls)), + } + + for _, url := range urls { + info.PolicyQualifiers = append(info.PolicyQualifiers, policyQualifierInfo{ + PolicyQualifierID: asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 2, 1}, + Qualifier: url, + }) + } + + bytes, _ := asn1.Marshal([]policyInformation{info}) + return bytes +} diff --git a/pki/config.go b/pki/config.go index c9bb304..0acd17c 100644 --- a/pki/config.go +++ b/pki/config.go @@ -23,7 +23,6 @@ type Config struct { PostalCode string `yaml:"postal_code,omitempty" json:"postal_code,omitempty"` CommonName string `yaml:"common_name,omitempty" json:"common_name,omitempty"` - EmailAddress []string `yaml:"email_address,omitempty" json:"email_address,omitempty"` OCSPServerURLs []string `yaml:"ocsp_server_ur_ls,omitempty" json:"ocsp_server_ur_ls,omitempty"` IssuingCertificateURLs []string `yaml:"issuing_certificate_urls,omitempty" json:"issuing_certificate_urls,omitempty"` CRLDistributionPointURLs []string `yaml:"crl_distribution_point_ur_ls,omitempty" json:"crl_distribution_point_ur_ls,omitempty"` @@ -61,18 +60,20 @@ func (v Config) Subject() pkix.Name { return result } -func (v Config) ExtraExtensions() []pkix.Extension { +func (v Config) extraExtensions() []pkix.Extension { var result []pkix.Extension - if len(v.IssuingCertificateURLs) > 0 { - for _, value := range stringsPrepare(v.CertificatePoliciesURLs) { - result = append(result, pkix.Extension{ - Id: asn1.ObjectIdentifier{2, 23, 140, 1, 1}, - Critical: true, - Value: []byte(value), - }) - } - + if len(v.CertificatePoliciesURLs) > 0 { + result = append(result, pkix.Extension{ + Id: asn1.ObjectIdentifier{2, 5, 29, 32}, + Critical: false, + Value: marshalPolicyCPSUrl(stringsPrepare(v.CertificatePoliciesURLs)...), + }) + } else { + result = append(result, pkix.Extension{ + Id: asn1.ObjectIdentifier{2, 5, 29, 32, 0}, + Critical: false, + }) } return result diff --git a/pki/encoders.go b/pki/encoders.go index e54de32..8dba232 100644 --- a/pki/encoders.go +++ b/pki/encoders.go @@ -92,13 +92,12 @@ func MarshalKeyPEM(key crypto.Signer) ([]byte, error) { } var prefix string - for name, a := range algorithms.Yield() { - if !a.IsPrivateKey(key) { - continue - } - - prefix = name.String() - } + //for name, a := range algorithms.Yield() { + // if !a.IsPrivateKey(key) { + // continue + // } + // prefix = name.String() + //} return CreatePEMBlock(b, PrivateKeyPEMBlock, prefix), nil } diff --git a/pki/generate_ca.go b/pki/generate_ca.go index 616d711..2aa1ecc 100644 --- a/pki/generate_ca.go +++ b/pki/generate_ca.go @@ -7,6 +7,7 @@ package pki import ( "crypto/rand" + "crypto/sha256" "crypto/x509" "fmt" "math/big" @@ -17,8 +18,9 @@ func NewCA( conf Config, deadline time.Duration, serialNumber int64, - withIntermediate bool, + intermediateCount int, ) (*Certificate, error) { + intermediateCount = max(0, intermediateCount) currTime := time.Now() template := &x509.Certificate{ @@ -29,23 +31,18 @@ func NewCA( Subject: conf.Subject(), NotBefore: currTime, NotAfter: currTime.Add(deadline), - KeyUsage: x509.KeyUsageCertSign | x509.KeyUsageCRLSign, + KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign | x509.KeyUsageCRLSign, OCSPServer: stringsPrepare(conf.OCSPServerURLs), IssuingCertificateURL: stringsPrepare(conf.IssuingCertificateURLs), CRLDistributionPoints: stringsPrepare(conf.CRLDistributionPointURLs), - ExtraExtensions: conf.ExtraExtensions(), - EmailAddresses: stringsPrepare(conf.EmailAddress), - MaxPathLenZero: false, - MaxPathLen: 1, + ExtraExtensions: conf.extraExtensions(), + MaxPathLen: intermediateCount, + MaxPathLenZero: intermediateCount <= 0, } - if withIntermediate { - template.MaxPathLen = 2 - } - - algName, ok := signatures.Get(conf.SignatureAlgorithm) + algName, ok := signatures.Get(template.SignatureAlgorithm) if !ok { - return nil, fmt.Errorf("unknown signature algorithm: %s", conf.SignatureAlgorithm.String()) + return nil, fmt.Errorf("unknown signature algorithm: %s", template.SignatureAlgorithm.String()) } alg, ok := algorithms.Get(algName) @@ -53,11 +50,19 @@ func NewCA( return nil, fmt.Errorf("unknown signature algorithm: %s", algName.String()) } - key, err := alg.Generate(RootCaCert) + key, err := alg.Generate(template.SignatureAlgorithm) if err != nil { return nil, fmt.Errorf("failed generating private key: %w", err) } + publicKeyBytes, err := x509.MarshalPKIXPublicKey(key.Public()) + if err != nil { + return nil, fmt.Errorf("failed marshaling public key: %w", err) + } + publicKeyHash := sha256.Sum256(publicKeyBytes) + template.SubjectKeyId = publicKeyHash[:20] + template.AuthorityKeyId = publicKeyHash[:20] + b, err := x509.CreateCertificate(rand.Reader, template, template, key.Public(), key) if err != nil { return nil, fmt.Errorf("failed generating certificate: %w", err) diff --git a/pki/generate_ca_inter.go b/pki/generate_ca_inter.go index 8aee808..464bcf1 100644 --- a/pki/generate_ca_inter.go +++ b/pki/generate_ca_inter.go @@ -19,24 +19,30 @@ func NewIntermediateCA( deadline time.Duration, serialNumber int64, ) (*Certificate, error) { + confSigAlg := conf.SignatureAlgorithm + if confSigAlg == x509.UnknownSignatureAlgorithm { + confSigAlg = rootCA.Crt.SignatureAlgorithm + } + + level := rootCA.Crt.MaxPathLen - 1 currTime := time.Now() template := &x509.Certificate{ IsCA: true, BasicConstraintsValid: true, - SignatureAlgorithm: rootCA.Crt.SignatureAlgorithm, + SignatureAlgorithm: confSigAlg, SerialNumber: big.NewInt(serialNumber), Subject: conf.Subject(), NotBefore: currTime, NotAfter: currTime.Add(deadline), - KeyUsage: x509.KeyUsageCertSign | x509.KeyUsageCRLSign, + KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign | x509.KeyUsageCRLSign, + ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth}, OCSPServer: stringsPrepare(conf.OCSPServerURLs), IssuingCertificateURL: stringsPrepare(conf.IssuingCertificateURLs), CRLDistributionPoints: stringsPrepare(conf.CRLDistributionPointURLs), - ExtraExtensions: conf.ExtraExtensions(), - EmailAddresses: stringsPrepare(conf.EmailAddress), - MaxPathLenZero: false, - MaxPathLen: 1, + ExtraExtensions: conf.extraExtensions(), + MaxPathLenZero: level <= 0, + MaxPathLen: level, } if !rootCA.IsValidPair() { @@ -47,7 +53,7 @@ func NewIntermediateCA( return nil, fmt.Errorf("invalid Root CA certificate: is not CA") } - if rootCA.Crt.MaxPathLen != 2 { + if template.MaxPathLen < 0 { return nil, fmt.Errorf("invalid Root CA certificate: not supported Intermediate CA") } @@ -65,7 +71,7 @@ func NewIntermediateCA( return nil, fmt.Errorf("unknown signature algorithm: %s", algName.String()) } - key, err := alg.Generate(InterCACert) + key, err := alg.Generate(template.SignatureAlgorithm) if err != nil { return nil, fmt.Errorf("failed generating private key: %w", err) } diff --git a/pki/generate_crt.go b/pki/generate_crt.go index 5cd68e7..71b10e9 100644 --- a/pki/generate_crt.go +++ b/pki/generate_crt.go @@ -7,6 +7,7 @@ package pki import ( "crypto/rand" + "crypto/sha256" "crypto/x509" "fmt" "math/big" @@ -28,26 +29,30 @@ func NewCRT( return nil, fmt.Errorf("invalid Root CA certificate: is not CA") } - if rootCA.Crt.MaxPathLen != 1 { + if rootCA.Crt.MaxPathLen != 0 { return nil, fmt.Errorf("invalid Root CA certificate: not supported generate client certificate") } + confSigAlg := conf.SignatureAlgorithm + if confSigAlg == x509.UnknownSignatureAlgorithm { + confSigAlg = rootCA.Crt.SignatureAlgorithm + } + currTime := time.Now() template := &x509.Certificate{ IsCA: false, BasicConstraintsValid: true, - SignatureAlgorithm: rootCA.Crt.SignatureAlgorithm, + SignatureAlgorithm: confSigAlg, SerialNumber: big.NewInt(serialNumber), Subject: conf.Subject(), NotBefore: currTime, NotAfter: currTime.Add(deadline), KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment, - ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth}, + ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, OCSPServer: stringsPrepare(conf.OCSPServerURLs), IssuingCertificateURL: stringsPrepare(conf.IssuingCertificateURLs), CRLDistributionPoints: stringsPrepare(conf.CRLDistributionPointURLs), - ExtraExtensions: conf.ExtraExtensions(), - EmailAddresses: stringsPrepare(conf.EmailAddress), + ExtraExtensions: conf.extraExtensions(), } if template.NotAfter.After(rootCA.Crt.NotAfter) { @@ -76,11 +81,18 @@ func NewCRT( return nil, fmt.Errorf("unknown signature algorithm: %s", algName.String()) } - key, err := alg.Generate(ClientCert) + key, err := alg.Generate(template.SignatureAlgorithm) if err != nil { return nil, fmt.Errorf("failed generating private key: %w", err) } + publicKeyBytes, err := x509.MarshalPKIXPublicKey(key.Public()) + if err != nil { + return nil, fmt.Errorf("failed marshaling public key: %w", err) + } + publicKeyHash := sha256.Sum256(publicKeyBytes) + template.SubjectKeyId = publicKeyHash[:20] + b, err := x509.CreateCertificate(rand.Reader, template, rootCA.Crt, key.Public(), rootCA.Key) if err != nil { return nil, fmt.Errorf("failed generating certificate: %w", err) diff --git a/pki/generate_csr.go b/pki/generate_csr.go index d269799..4832b96 100644 --- a/pki/generate_csr.go +++ b/pki/generate_csr.go @@ -7,6 +7,7 @@ package pki import ( "crypto/rand" + "crypto/sha256" "crypto/x509" "fmt" "math/big" @@ -43,7 +44,7 @@ func NewCSR(signatureAlgorithm x509.SignatureAlgorithm, domains ...string) (*Req template.Subject.CommonName = template.IPAddresses[0].String() } - key, err := alg.Generate(ClientCert) + key, err := alg.Generate(template.SignatureAlgorithm) if err != nil { return nil, fmt.Errorf("failed generating private key: %w", err) } @@ -76,33 +77,45 @@ func SignCSR( return nil, fmt.Errorf("invalid Root CA certificate: is not CA") } - if rootCA.Crt.MaxPathLen != 1 { + if rootCA.Crt.MaxPathLen != 0 { return nil, fmt.Errorf("invalid Root CA certificate: not supported generate client certificate") } - if _, ok := signatures.Get(csr.SignatureAlgorithm); !ok { - return nil, fmt.Errorf("unknown signature algorithm: %s", csr.SignatureAlgorithm.String()) + confSigAlg := conf.SignatureAlgorithm + if confSigAlg == x509.UnknownSignatureAlgorithm { + confSigAlg = rootCA.Crt.SignatureAlgorithm + } + + if _, ok := signatures.Get(confSigAlg); !ok { + return nil, fmt.Errorf("unknown signature algorithm: %s", confSigAlg.String()) } currTime := time.Now() template := &x509.Certificate{ IsCA: false, BasicConstraintsValid: true, - SignatureAlgorithm: rootCA.Crt.SignatureAlgorithm, + SignatureAlgorithm: confSigAlg, SerialNumber: big.NewInt(serialNumber), Subject: csr.Subject, NotBefore: currTime, NotAfter: currTime.Add(deadline), KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment, - ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth}, - OCSPServer: rootCA.Crt.OCSPServer, + ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, + OCSPServer: stringsPrepare(conf.OCSPServerURLs), IssuingCertificateURL: stringsPrepare(conf.IssuingCertificateURLs), - CRLDistributionPoints: rootCA.Crt.CRLDistributionPoints, - EmailAddresses: rootCA.Crt.EmailAddresses, + CRLDistributionPoints: stringsPrepare(conf.CRLDistributionPointURLs), + ExtraExtensions: conf.extraExtensions(), DNSNames: csr.DNSNames, IPAddresses: csr.IPAddresses, } + publicKeyBytes, err := x509.MarshalPKIXPublicKey(csr.PublicKey) + if err != nil { + return nil, fmt.Errorf("failed marshaling public key: %w", err) + } + publicKeyHash := sha256.Sum256(publicKeyBytes) + template.SubjectKeyId = publicKeyHash[:20] + b, err := x509.CreateCertificate(rand.Reader, template, rootCA.Crt, csr.PublicKey, rootCA.Key) if err != nil { return nil, fmt.Errorf("failed generating certificate: %w", err) diff --git a/pki/generate_test.go b/pki/generate_test.go index 4cffbad..b1cb9e4 100644 --- a/pki/generate_test.go +++ b/pki/generate_test.go @@ -16,18 +16,28 @@ import ( "go.osspkg.com/encrypt/pki" ) -func TestUnit_Generate(t *testing.T) { +func TestUnit_Generate_ECDSA(t *testing.T) { rootCa, err := pki.NewCA( - pki.Config{SignatureAlgorithm: x509.ECDSAWithSHA512, CommonName: "Test Root CA"}, + pki.Config{ + SignatureAlgorithm: x509.ECDSAWithSHA256, + CommonName: "Test Root CA", + }, time.Hour*24*365*10, time.Now().Unix(), - true, + 1, ) casecheck.NoError(t, err) dump(t, rootCa) subCa, err := pki.NewIntermediateCA( - pki.Config{CommonName: "Test Web CA"}, + pki.Config{ + SignatureAlgorithm: x509.ECDSAWithSHA256, + CommonName: "Test Web CA", + OCSPServerURLs: []string{"http://ocsp.test.com"}, + CRLDistributionPointURLs: []string{"http://pki.test.com/cert.crl"}, + IssuingCertificateURLs: []string{"http://pki.test.com/cert.crt"}, + CertificatePoliciesURLs: []string{"http://pki.test.com/policy.pdf"}, + }, *rootCa, time.Hour*24*365*5, time.Now().Unix(), @@ -36,7 +46,62 @@ func TestUnit_Generate(t *testing.T) { dump(t, subCa) crt, err := pki.NewCRT( - pki.Config{CommonName: "Test Web CA"}, + pki.Config{ + SignatureAlgorithm: x509.ECDSAWithSHA256, + CommonName: "Test Web Ltd", + OCSPServerURLs: []string{"http://ocsp.test.com"}, + CRLDistributionPointURLs: []string{"http://pki.test.com/cert.crl"}, + IssuingCertificateURLs: []string{"http://pki.test.com/cert.crt"}, + CertificatePoliciesURLs: []string{"http://pki.test.com/policy.pdf"}, + }, + *subCa, + time.Hour*24*90, + time.Now().Unix(), + "localhost", + ) + casecheck.NoError(t, err) + dump(t, crt) +} + +func TestUnit_Generate_RSA(t *testing.T) { + rootCa, err := pki.NewCA( + pki.Config{ + SignatureAlgorithm: x509.SHA384WithRSA, + CommonName: "Test Root CA", + CertificatePoliciesURLs: []string{"http://pki.test.com/policy.pdf"}, + }, + time.Hour*24*365*10, + time.Now().Unix(), + 1, + ) + casecheck.NoError(t, err) + dump(t, rootCa) + + subCa, err := pki.NewIntermediateCA( + pki.Config{ + SignatureAlgorithm: x509.SHA384WithRSA, + CommonName: "Test Web CA", + CertificatePoliciesURLs: []string{"http://pki.test.com/policy.pdf"}, + OCSPServerURLs: []string{"http://ocsp.test.com"}, + CRLDistributionPointURLs: []string{"http://pki.test.com/cert.crl"}, + IssuingCertificateURLs: []string{"http://pki.test.com/cert.crt"}, + }, + *rootCa, + time.Hour*24*365*5, + time.Now().Unix(), + ) + casecheck.NoError(t, err) + dump(t, subCa) + + crt, err := pki.NewCRT( + pki.Config{ + SignatureAlgorithm: x509.SHA384WithRSA, + CommonName: "Test Web Ltd", + CertificatePoliciesURLs: []string{"http://pki.test.com/policy.pdf"}, + OCSPServerURLs: []string{"http://ocsp.test.com"}, + CRLDistributionPointURLs: []string{"http://pki.test.com/cert.crl"}, + IssuingCertificateURLs: []string{"http://pki.test.com/cert.crt"}, + }, *subCa, time.Hour*24*90, time.Now().Unix(), @@ -51,7 +116,7 @@ func TestUnit_SignCSR(t *testing.T) { pki.Config{SignatureAlgorithm: x509.ECDSAWithSHA512, CommonName: "Test Root CA"}, time.Hour*24*365*10, time.Now().Unix(), - true, + 1, ) casecheck.NoError(t, err) dump(t, rootCa) @@ -65,7 +130,7 @@ func TestUnit_SignCSR(t *testing.T) { casecheck.NoError(t, err) dump(t, subCa) - csr, err := pki.NewCSR(x509.SHA384WithRSA, "localhost") + csr, err := pki.NewCSR(x509.SHA384WithRSAPSS, "localhost") casecheck.NoError(t, err) crt, err := pki.SignCSR(pki.Config{}, *subCa, *csr.Csr, time.Hour*24*90, time.Now().Unix()) @@ -85,45 +150,27 @@ func dump(t *testing.T, crt *pki.Certificate) { } func dumpCertificateInfo(cert *x509.Certificate) { - fmt.Println("------------------------------------------------------------------") - fmt.Println(" ИНФОРМАЦИЯ О СЕРТИФИКАТЕ") - fmt.Println("------------------------------------------------------------------") - - // Субъект и Издатель - fmt.Printf("Субъект (Subject): %v\n", cert.Subject.ToRDNSequence()) - fmt.Printf("Издатель (Issuer): %v\n", cert.Issuer.ToRDNSequence()) - - // Основные идентификаторы - fmt.Printf("Общее имя (Common Name): %s\n", cert.Subject.CommonName) - fmt.Printf("Серийный номер: %s\n", cert.SerialNumber.String()) - - // Срок действия - fmt.Printf("Действителен с: %s\n", cert.NotBefore.Format("2006-01-02 15:04:05 MST")) - fmt.Printf("Действителен до: %s\n", cert.NotAfter.Format("2006-01-02 15:04:05 MST")) - - // SANs (Subject Alternative Names) - if len(cert.DNSNames) > 0 { - fmt.Printf("DNS SANs: %v\n", cert.DNSNames) - } - if len(cert.IPAddresses) > 0 { - fmt.Printf("IP SANs: %v\n", cert.IPAddresses) - } - - // Алгоритмы - fmt.Printf("Алгоритм подписи: %v\n", cert.SignatureAlgorithm.String()) - fmt.Printf("Алгоритм публичного ключа: %v\n", cert.PublicKeyAlgorithm.String()) - - // Использование ключа (Key Usage) - fmt.Printf("Базовое использование ключа: %v\n", cert.KeyUsage) - if len(cert.ExtKeyUsage) > 0 { - fmt.Printf("Расширенное использование ключа: %v\n", cert.ExtKeyUsage) - } - - // Флаги CA - fmt.Printf("Является CA: %t\n", cert.IsCA) - if cert.MaxPathLen > 0 { - fmt.Printf("Макс. длина пути (MaxPathLen): %d\n", cert.MaxPathLen) - } - - fmt.Println("------------------------------------------------------------------") + fmt.Println("-------------------------------------------------------------------------") + fmt.Println(" ИНФОРМАЦИЯ О СЕРТИФИКАТЕ") + fmt.Println("-------------------------------------------------------------------------") + fmt.Printf("Субъект (Subject): %v\n", cert.Subject.ToRDNSequence()) + fmt.Printf("SubjectKeyId: %x\n", cert.SubjectKeyId) + fmt.Printf("Издатель (Issuer): %v\n", cert.Issuer.ToRDNSequence()) + fmt.Printf("AuthorityKeyId: %x\n", cert.AuthorityKeyId) + fmt.Printf("Общее имя (Common Name): %s\n", cert.Subject.CommonName) + fmt.Printf("Серийный номер: %s\n", cert.SerialNumber.String()) + fmt.Printf("Действителен с: %s\n", cert.NotBefore.Format("2006-01-02 15:04:05 MST")) + fmt.Printf("Действителен до: %s\n", cert.NotAfter.Format("2006-01-02 15:04:05 MST")) + fmt.Printf("DNS SANs: %v\n", cert.DNSNames) + fmt.Printf("IP SANs: %v\n", cert.IPAddresses) + fmt.Printf("Алгоритм подписи: %v\n", cert.SignatureAlgorithm.String()) + fmt.Printf("Алгоритм публичного ключа: %v\n", cert.PublicKeyAlgorithm.String()) + fmt.Printf("Базовое использование ключа: %v\n", cert.KeyUsage) + fmt.Printf("Расширенное использование ключа: %v\n", cert.ExtKeyUsage) + fmt.Printf("Является CA: %t\n", cert.IsCA) + fmt.Printf("Макс. длина пути (MaxPathLen): %d\n", cert.MaxPathLen) + fmt.Printf("CRL: %v\n", cert.CRLDistributionPoints) + fmt.Printf("OCSP: %v\n", cert.OCSPServer) + fmt.Printf("Certificate URL: %v\n", cert.IssuingCertificateURL) + fmt.Println("-------------------------------------------------------------------------") }