"encoding/asn1"
"errors"
"fmt"
+
+ "golang.org/x/crypto/cryptobyte"
+ cryptobyte_asn1 "golang.org/x/crypto/cryptobyte/asn1"
+
+ "crypto/go.cypherpunks.ru/gogost/v5/gost3410"
)
// pkcs8 reflects an ASN.1, PKCS #8 PrivateKey. See
// MarshalPKCS8PrivateKey converts a private key to PKCS #8, ASN.1 DER form.
//
-// The following key types are currently supported: *rsa.PrivateKey, *ecdsa.PrivateKey
-// and ed25519.PrivateKey. Unsupported key types result in an error.
+// The following key types are currently supported: *rsa.PrivateKey, *ecdsa.PrivateKey,
+// GOST R 34.10-2012 and ed25519.PrivateKey. Unsupported key types result in an error.
//
// This kind of key is commonly encoded in PEM blocks of type "PRIVATE KEY".
func MarshalPKCS8PrivateKey(key interface{}) ([]byte, error) {
}
privKey.PrivateKey = curvePrivateKey
+ case *gost3410.PrivateKey:
+ builder := cryptobyte.NewBuilder(nil)
+ switch k.C.Name {
+ case "id-tc26-gost-3410-2012-256-paramSetA":
+ privKey.Algo.Algorithm = oidTc26Gost34102012256
+ builder.AddASN1(cryptobyte_asn1.SEQUENCE, func(b *cryptobyte.Builder) {
+ b.AddASN1ObjectIdentifier(oidTc26Gost34102012256ParamSetA)
+ })
+ case "id-tc26-gost-3410-2012-256-paramSetB":
+ privKey.Algo.Algorithm = oidTc26Gost34102012256
+ builder.AddASN1(cryptobyte_asn1.SEQUENCE, func(b *cryptobyte.Builder) {
+ b.AddASN1ObjectIdentifier(oidTc26Gost34102012256ParamSetB)
+ })
+ case "id-tc26-gost-3410-2012-256-paramSetC":
+ privKey.Algo.Algorithm = oidTc26Gost34102012256
+ builder.AddASN1(cryptobyte_asn1.SEQUENCE, func(b *cryptobyte.Builder) {
+ b.AddASN1ObjectIdentifier(oidTc26Gost34102012256ParamSetC)
+ })
+ case "id-tc26-gost-3410-2012-256-paramSetD":
+ privKey.Algo.Algorithm = oidTc26Gost34102012256
+ builder.AddASN1(cryptobyte_asn1.SEQUENCE, func(b *cryptobyte.Builder) {
+ b.AddASN1ObjectIdentifier(oidTc26Gost34102012256ParamSetD)
+ })
+ case "id-tc26-gost-3410-12-512-paramSetA":
+ privKey.Algo.Algorithm = oidTc26Gost34102012512
+ builder.AddASN1(cryptobyte_asn1.SEQUENCE, func(b *cryptobyte.Builder) {
+ b.AddASN1ObjectIdentifier(oidTc26Gost34102012512ParamSetA)
+ })
+ case "id-tc26-gost-3410-12-512-paramSetB":
+ privKey.Algo.Algorithm = oidTc26Gost34102012512
+ builder.AddASN1(cryptobyte_asn1.SEQUENCE, func(b *cryptobyte.Builder) {
+ b.AddASN1ObjectIdentifier(oidTc26Gost34102012512ParamSetB)
+ })
+ case "id-tc26-gost-3410-2012-512-paramSetC":
+ privKey.Algo.Algorithm = oidTc26Gost34102012512
+ builder.AddASN1(cryptobyte_asn1.SEQUENCE, func(b *cryptobyte.Builder) {
+ b.AddASN1ObjectIdentifier(oidTc26Gost34102012512ParamSetC)
+ })
+ }
+ var err error
+ privKey.Algo.Parameters.FullBytes, err = builder.Bytes()
+ if err != nil {
+ return nil, err
+ }
+ builder = cryptobyte.NewBuilder(nil)
+ builder.AddASN1OctetString(k.Raw())
+ privKey.PrivateKey, err = builder.Bytes()
+ if err != nil {
+ return nil, err
+ }
+
default:
return nil, fmt.Errorf("x509: unknown key type while marshaling PKCS#8: %T", key)
}