smx509: fix CSRResponse sign certs handle issue

This commit is contained in:
Sun Yimin 2024-06-18 11:43:20 +08:00 committed by GitHub
parent a1de6312b4
commit 0445d16e97
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 31 additions and 12 deletions

View File

@ -55,6 +55,10 @@
3. 如果签名数据中不包含证书项,则手动设置验签证书(参考```TestSkipCertificates```
4. 调用```Verify```或```VerifyWithChain```方法。
#### 特殊方法
```DegenerateCertificate```退化成签名数据中只包含证书目前没有使用SM2 OID的方法如果需要可以请求添加。可以参考```TestDegenerateCertificate```和```TestParseSM2CertificateChain```。
### 签名及数字信封数据Signed and Enveloped Data
签名和数字信封数据使用场景较少有些实现用它来传输私钥譬如www.gmcert.org。具体请参考```sign_enveloped_test.go```。

View File

@ -37,7 +37,7 @@ func NewSignedData(data []byte) (*SignedData, error) {
}
ci := contentInfo{
ContentType: OIDData,
Content: asn1.RawValue{Class: 2, Tag: 0, Bytes: content, IsCompound: true},
Content: asn1.RawValue{Class: asn1.ClassContextSpecific, Tag: 0, Bytes: content, IsCompound: true},
}
sd := signedData{
ContentInfo: ci,

View File

@ -20,8 +20,16 @@ type CSRResponse struct {
EncryptCerts []*Certificate
}
// GM/T 0092-2020 Specification of certificate request syntax based on SM2 cryptographic algorithm.
// Section 8 and Appendix A
//
// CSRResponse ::= SEQUENCE {
// signCertificate CertificateSet,
// encryptedPrivateKey [0] SM2EnvelopedKey OPTIONAL,
// encryptCertificate [1] CertificateSet OPTIONAL
// }
type tbsCSRResponse struct {
SignCerts rawCertificates
SignCerts []asn1.RawValue `asn1:"set"` // SignCerts ::= SET OF Certificate
EncryptedPrivateKey asn1.RawValue `asn1:"optional,tag:0"`
EncryptCerts rawCertificates `asn1:"optional,tag:1"`
}
@ -39,9 +47,14 @@ func ParseCSRResponse(signPrivateKey *sm2.PrivateKey, der []byte) (CSRResponse,
if err != nil || len(rest) > 0 {
return result, errors.New("smx509: invalid CSRResponse asn1 data")
}
signCerts, err := resp.SignCerts.Parse()
if err != nil || len(signCerts) == 0 {
return result, errors.New("smx509: invalid sign certificates")
signCerts := make([]*Certificate, len(resp.SignCerts))
for i, rawCert := range resp.SignCerts {
signCert, err := ParseCertificate(rawCert.FullBytes)
if err != nil {
return result, err
}
signCerts[i] = signCert
}
// check sign public key against the private key
@ -98,13 +111,16 @@ func MarshalCSRResponse(signCerts []*Certificate, encryptPrivateKey *sm2.Private
}
resp := tbsCSRResponse{}
resp.SignCerts = marshalCertificates(signCerts)
resp.SignCerts = make([]asn1.RawValue, 0, len(signCerts))
for _, cert := range signCerts {
resp.SignCerts = append(resp.SignCerts, asn1.RawValue{FullBytes: cert.Raw})
}
if encryptPrivateKey != nil && len(encryptCerts) > 0 {
privateKeyBytes, err := sm2.MarshalEnvelopedPrivateKey(rand.Reader, signPubKey, encryptPrivateKey)
if err != nil {
return nil, err
}
resp.EncryptedPrivateKey = asn1.RawValue{Class: 2, Tag: 0, IsCompound: true, Bytes: privateKeyBytes}
resp.EncryptedPrivateKey = asn1.RawValue{Class: asn1.ClassContextSpecific, Tag: 0, IsCompound: true, Bytes: privateKeyBytes}
resp.EncryptCerts = marshalCertificates(encryptCerts)
}
return asn1.Marshal(resp)
@ -124,7 +140,7 @@ func marshalCertificates(certs []*Certificate) rawCertificates {
// RawContent, we have to encode it into the RawContent. If its missing,
// then `asn1.Marshal()` will strip out the certificate wrapper instead.
func marshalCertificateBytes(certs []byte) (rawCertificates, error) {
var val = asn1.RawValue{Bytes: certs, Class: 2, Tag: 0, IsCompound: true}
var val = asn1.RawValue{Bytes: certs, Class: asn1.ClassContextSpecific, Tag: 0, IsCompound: true}
b, err := asn1.Marshal(val)
if err != nil {
return rawCertificates{}, err

View File

@ -113,7 +113,6 @@ func TestMarshalCSRResponse(t *testing.T) {
// Call the function
result, err := smx509.MarshalCSRResponse([]*smx509.Certificate{pairs[0].Certificate, pairs[2].Certificate}, encPrivKey, []*smx509.Certificate{pairs[1].Certificate, pairs[2].Certificate})
// Check the result
if err != nil {
t.Errorf("Unexpected error: %v", err)
@ -154,17 +153,17 @@ func TestMarshalCSRResponse(t *testing.T) {
}
_, err = smx509.MarshalCSRResponse(nil, nil, nil)
if err == nil || err.Error() != "smx509: no sign certificate" {
if err == nil || err.Error() != "smx509: no sign certificate" {
t.Errorf("Unexpected error: %v", err)
}
_, err = smx509.MarshalCSRResponse([]*smx509.Certificate{pairs[0].Certificate, pairs[2].Certificate}, encPrivKey, nil)
if err == nil || err.Error() != "smx509: missing encrypt certificate" {
if err == nil || err.Error() != "smx509: missing encrypt certificate" {
t.Errorf("Unexpected error: %v", err)
}
_, err = smx509.MarshalCSRResponse([]*smx509.Certificate{pairs[0].Certificate, pairs[2].Certificate}, encPrivKey, []*smx509.Certificate{pairs[2].Certificate})
if err == nil || err.Error() != "smx509: encrypt key pair mismatch" {
if err == nil || err.Error() != "smx509: encrypt key pair mismatch" {
t.Errorf("Unexpected error: %v", err)
}
}