mirror of
https://github.com/emmansun/gmsm.git
synced 2025-04-26 04:06:18 +08:00
support cfca certificate request #286
This commit is contained in:
parent
1d894ef955
commit
df3db923c6
@ -11,6 +11,8 @@ import (
|
|||||||
"github.com/emmansun/gmsm/smx509"
|
"github.com/emmansun/gmsm/smx509"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type CertificateRequest = smx509.CertificateRequestCFCA
|
||||||
|
|
||||||
// CreateCertificateRequest creates a new certificate request based on a template.
|
// CreateCertificateRequest creates a new certificate request based on a template.
|
||||||
// The following members of template are used: Subject.
|
// The following members of template are used: Subject.
|
||||||
// The certPriv is the private key for the certificate, and the tmpPriv is the temporary private key for returning encryption key decryption.
|
// The certPriv is the private key for the certificate, and the tmpPriv is the temporary private key for returning encryption key decryption.
|
||||||
@ -18,3 +20,8 @@ import (
|
|||||||
func CreateCertificateRequest(rand io.Reader, template *x509.CertificateRequest, certPriv, tmpPriv any, challengePassword string) ([]byte, error) {
|
func CreateCertificateRequest(rand io.Reader, template *x509.CertificateRequest, certPriv, tmpPriv any, challengePassword string) ([]byte, error) {
|
||||||
return smx509.CreateCFCACertificateRequest(rand, template, certPriv, tmpPriv, challengePassword)
|
return smx509.CreateCFCACertificateRequest(rand, template, certPriv, tmpPriv, challengePassword)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ParseCertificateRequest parses a certificate request from the given DER data.
|
||||||
|
func ParseCertificateRequest(der []byte) (*CertificateRequest, error) {
|
||||||
|
return smx509.ParseCFCACertificateRequest(der)
|
||||||
|
}
|
||||||
|
@ -13,7 +13,6 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/emmansun/gmsm/sm2"
|
"github.com/emmansun/gmsm/sm2"
|
||||||
"github.com/emmansun/gmsm/smx509"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestCreateCertificateRequest(t *testing.T) {
|
func TestCreateCertificateRequest(t *testing.T) {
|
||||||
@ -57,11 +56,20 @@ func TestCreateCertificateRequest(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
csr, err := smx509.ParseCertificateRequest(csrDer)
|
csr, err := ParseCertificateRequest(csrDer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if csr.Subject.CommonName != "certRequisition" {
|
if csr.Subject.CommonName != "certRequisition" {
|
||||||
t.Fatal("common name not match")
|
t.Fatal("common name not match")
|
||||||
}
|
}
|
||||||
|
if csr.Subject.CommonName != "certRequisition" {
|
||||||
|
t.Fatal("common name not match")
|
||||||
|
}
|
||||||
|
if csr.ChallengePassword != "111111" {
|
||||||
|
t.Fatal("challenge password not match")
|
||||||
|
}
|
||||||
|
if csr.TmpPublicKey == nil {
|
||||||
|
t.Fatal("tmp public key not match")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
package smx509
|
package smx509
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"crypto"
|
"crypto"
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
@ -162,3 +163,56 @@ func buildTmpPublicKeyAttr(rawAttributes []asn1.RawValue, tmpPriv any) ([]asn1.R
|
|||||||
|
|
||||||
return append(rawAttributes, rawValue), nil
|
return append(rawAttributes, rawValue), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CertificateRequestCFCA represents a CFCA certificate request.
|
||||||
|
type CertificateRequestCFCA struct {
|
||||||
|
CertificateRequest
|
||||||
|
ChallengePassword string
|
||||||
|
TmpPublicKey any
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseCFCACertificateRequest parses a CFCA certificate request from the given DER data.
|
||||||
|
func ParseCFCACertificateRequest(asn1Data []byte) (*CertificateRequestCFCA, error) {
|
||||||
|
var csr certificateRequest
|
||||||
|
|
||||||
|
rest, err := asn1.Unmarshal(asn1Data, &csr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else if len(rest) != 0 {
|
||||||
|
return nil, asn1.SyntaxError{Msg: "trailing data"}
|
||||||
|
}
|
||||||
|
|
||||||
|
inner, err := parseCertificateRequest(&csr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
out := &CertificateRequestCFCA{
|
||||||
|
CertificateRequest: *inner,
|
||||||
|
}
|
||||||
|
parseCFCAAttributes(out, csr.TBSCSR.RawAttributes)
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseCFCAAttributes(out *CertificateRequestCFCA, rawAttributes []asn1.RawValue) {
|
||||||
|
var value struct {
|
||||||
|
Type asn1.ObjectIdentifier
|
||||||
|
Value asn1.RawValue
|
||||||
|
}
|
||||||
|
for _, attr := range rawAttributes {
|
||||||
|
if _, err := asn1.Unmarshal(attr.FullBytes, &value); err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
switch {
|
||||||
|
case value.Type.Equal(oidChallengePassword):
|
||||||
|
asn1.Unmarshal(value.Value.FullBytes, &out.ChallengePassword)
|
||||||
|
case value.Type.Equal(oidTmpPublicKey):
|
||||||
|
var keyBytes []byte
|
||||||
|
asn1.Unmarshal(value.Value.FullBytes, &keyBytes)
|
||||||
|
if len(keyBytes) == 136 && bytes.Equal(tmpPublicKeyPrefix, keyBytes[:8]) {
|
||||||
|
// parse the public key
|
||||||
|
copy(keyBytes[40:72], keyBytes[72:104])
|
||||||
|
out.TmpPublicKey, _ = sm2.NewPublicKey(keyBytes[8:72])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -56,11 +56,17 @@ func TestCreateCFCACertificateRequest(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
csr, err := ParseCertificateRequest(csrDer)
|
csr, err := ParseCFCACertificateRequest(csrDer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if csr.Subject.CommonName != "certRequisition" {
|
if csr.Subject.CommonName != "certRequisition" {
|
||||||
t.Fatal("common name not match")
|
t.Fatal("common name not match")
|
||||||
}
|
}
|
||||||
|
if csr.ChallengePassword != "111111" {
|
||||||
|
t.Fatal("challenge password not match")
|
||||||
|
}
|
||||||
|
if csr.TmpPublicKey == nil {
|
||||||
|
t.Fatal("tmp public key not match")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user