mirror of
https://github.com/emmansun/gmsm.git
synced 2025-04-28 05:06:18 +08:00
pkcs1
This commit is contained in:
parent
dc34e17797
commit
0f7a9070ee
268
smx509/pem_decrypt.go
Normal file
268
smx509/pem_decrypt.go
Normal file
@ -0,0 +1,268 @@
|
|||||||
|
// Copyright 2012 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package smx509
|
||||||
|
|
||||||
|
// RFC 1423 describes the encryption of PEM blocks. The algorithm used to
|
||||||
|
// generate a key from the password was derived by looking at the OpenSSL
|
||||||
|
// implementation.
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/aes"
|
||||||
|
"crypto/cipher"
|
||||||
|
"crypto/des"
|
||||||
|
"crypto/md5"
|
||||||
|
"encoding/hex"
|
||||||
|
"encoding/pem"
|
||||||
|
"errors"
|
||||||
|
"io"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/emmansun/gmsm/sm4"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PEMCipher int
|
||||||
|
|
||||||
|
// Possible values for the EncryptPEMBlock encryption algorithm.
|
||||||
|
const (
|
||||||
|
_ PEMCipher = iota
|
||||||
|
PEMCipherDES
|
||||||
|
PEMCipher3DES
|
||||||
|
PEMCipherAES128
|
||||||
|
PEMCipherAES192
|
||||||
|
PEMCipherAES256
|
||||||
|
PEMCipherSM4
|
||||||
|
)
|
||||||
|
|
||||||
|
// rfc1423Algo holds a method for enciphering a PEM block.
|
||||||
|
type rfc1423Algo struct {
|
||||||
|
cipher PEMCipher
|
||||||
|
name string
|
||||||
|
cipherFunc func(key []byte) (cipher.Block, error)
|
||||||
|
keySize int
|
||||||
|
blockSize int
|
||||||
|
}
|
||||||
|
|
||||||
|
// rfc1423Algos holds a slice of the possible ways to encrypt a PEM
|
||||||
|
// block. The ivSize numbers were taken from the OpenSSL source.
|
||||||
|
var rfc1423Algos = []rfc1423Algo{{
|
||||||
|
cipher: PEMCipherDES,
|
||||||
|
name: "DES-CBC",
|
||||||
|
cipherFunc: des.NewCipher,
|
||||||
|
keySize: 8,
|
||||||
|
blockSize: des.BlockSize,
|
||||||
|
}, {
|
||||||
|
cipher: PEMCipher3DES,
|
||||||
|
name: "DES-EDE3-CBC",
|
||||||
|
cipherFunc: des.NewTripleDESCipher,
|
||||||
|
keySize: 24,
|
||||||
|
blockSize: des.BlockSize,
|
||||||
|
}, {
|
||||||
|
cipher: PEMCipherAES128,
|
||||||
|
name: "AES-128-CBC",
|
||||||
|
cipherFunc: aes.NewCipher,
|
||||||
|
keySize: 16,
|
||||||
|
blockSize: aes.BlockSize,
|
||||||
|
}, {
|
||||||
|
cipher: PEMCipherAES192,
|
||||||
|
name: "AES-192-CBC",
|
||||||
|
cipherFunc: aes.NewCipher,
|
||||||
|
keySize: 24,
|
||||||
|
blockSize: aes.BlockSize,
|
||||||
|
}, {
|
||||||
|
cipher: PEMCipherAES256,
|
||||||
|
name: "AES-256-CBC",
|
||||||
|
cipherFunc: aes.NewCipher,
|
||||||
|
keySize: 32,
|
||||||
|
blockSize: aes.BlockSize,
|
||||||
|
}, {
|
||||||
|
cipher: PEMCipherSM4,
|
||||||
|
name: "SM4-CBC",
|
||||||
|
cipherFunc: sm4.NewCipher,
|
||||||
|
keySize: 16,
|
||||||
|
blockSize: sm4.BlockSize,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// deriveKey uses a key derivation function to stretch the password into a key
|
||||||
|
// with the number of bits our cipher requires. This algorithm was derived from
|
||||||
|
// the OpenSSL source.
|
||||||
|
func (c rfc1423Algo) deriveKey(password, salt []byte) []byte {
|
||||||
|
hash := md5.New()
|
||||||
|
out := make([]byte, c.keySize)
|
||||||
|
var digest []byte
|
||||||
|
|
||||||
|
for i := 0; i < len(out); i += len(digest) {
|
||||||
|
hash.Reset()
|
||||||
|
hash.Write(digest)
|
||||||
|
hash.Write(password)
|
||||||
|
hash.Write(salt)
|
||||||
|
digest = hash.Sum(digest[:0])
|
||||||
|
copy(out[i:], digest)
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsEncryptedPEMBlock returns whether the PEM block is password encrypted
|
||||||
|
// according to RFC 1423.
|
||||||
|
//
|
||||||
|
// Deprecated: Legacy PEM encryption as specified in RFC 1423 is insecure by
|
||||||
|
// design. Since it does not authenticate the ciphertext, it is vulnerable to
|
||||||
|
// padding oracle attacks that can let an attacker recover the plaintext.
|
||||||
|
func IsEncryptedPEMBlock(b *pem.Block) bool {
|
||||||
|
_, ok := b.Headers["DEK-Info"]
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
|
// IncorrectPasswordError is returned when an incorrect password is detected.
|
||||||
|
var IncorrectPasswordError = errors.New("x509: decryption password incorrect")
|
||||||
|
|
||||||
|
// DecryptPEMBlock takes a PEM block encrypted according to RFC 1423 and the
|
||||||
|
// password used to encrypt it and returns a slice of decrypted DER encoded
|
||||||
|
// bytes. It inspects the DEK-Info header to determine the algorithm used for
|
||||||
|
// decryption. If no DEK-Info header is present, an error is returned. If an
|
||||||
|
// incorrect password is detected an IncorrectPasswordError is returned. Because
|
||||||
|
// of deficiencies in the format, it's not always possible to detect an
|
||||||
|
// incorrect password. In these cases no error will be returned but the
|
||||||
|
// decrypted DER bytes will be random noise.
|
||||||
|
//
|
||||||
|
// Deprecated: Legacy PEM encryption as specified in RFC 1423 is insecure by
|
||||||
|
// design. Since it does not authenticate the ciphertext, it is vulnerable to
|
||||||
|
// padding oracle attacks that can let an attacker recover the plaintext.
|
||||||
|
func DecryptPEMBlock(b *pem.Block, password []byte) ([]byte, error) {
|
||||||
|
dek, ok := b.Headers["DEK-Info"]
|
||||||
|
if !ok {
|
||||||
|
return nil, errors.New("x509: no DEK-Info header in block")
|
||||||
|
}
|
||||||
|
// [Emman] strings.Cut is supported since golang 1.18.
|
||||||
|
//
|
||||||
|
// mode, hexIV, ok := strings.Cut(dek, ",")
|
||||||
|
// if !ok {
|
||||||
|
// return nil, errors.New("x509: malformed DEK-Info header")
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
idx := strings.Index(dek, ",")
|
||||||
|
if idx == -1 {
|
||||||
|
return nil, errors.New("x509: malformed DEK-Info header")
|
||||||
|
}
|
||||||
|
|
||||||
|
mode, hexIV := dek[:idx], dek[idx+1:]
|
||||||
|
ciph := cipherByName(mode)
|
||||||
|
if ciph == nil {
|
||||||
|
return nil, errors.New("x509: unknown encryption mode")
|
||||||
|
}
|
||||||
|
iv, err := hex.DecodeString(hexIV)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(iv) != ciph.blockSize {
|
||||||
|
return nil, errors.New("x509: incorrect IV size")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Based on the OpenSSL implementation. The salt is the first 8 bytes
|
||||||
|
// of the initialization vector.
|
||||||
|
key := ciph.deriveKey(password, iv[:8])
|
||||||
|
block, err := ciph.cipherFunc(key)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(b.Bytes)%block.BlockSize() != 0 {
|
||||||
|
return nil, errors.New("x509: encrypted PEM data is not a multiple of the block size")
|
||||||
|
}
|
||||||
|
|
||||||
|
data := make([]byte, len(b.Bytes))
|
||||||
|
dec := cipher.NewCBCDecrypter(block, iv)
|
||||||
|
dec.CryptBlocks(data, b.Bytes)
|
||||||
|
|
||||||
|
// Blocks are padded using a scheme where the last n bytes of padding are all
|
||||||
|
// equal to n. It can pad from 1 to blocksize bytes inclusive. See RFC 1423.
|
||||||
|
// For example:
|
||||||
|
// [x y z 2 2]
|
||||||
|
// [x y 7 7 7 7 7 7 7]
|
||||||
|
// If we detect a bad padding, we assume it is an invalid password.
|
||||||
|
dlen := len(data)
|
||||||
|
if dlen == 0 || dlen%ciph.blockSize != 0 {
|
||||||
|
return nil, errors.New("x509: invalid padding")
|
||||||
|
}
|
||||||
|
last := int(data[dlen-1])
|
||||||
|
if dlen < last {
|
||||||
|
return nil, IncorrectPasswordError
|
||||||
|
}
|
||||||
|
if last == 0 || last > ciph.blockSize {
|
||||||
|
return nil, IncorrectPasswordError
|
||||||
|
}
|
||||||
|
for _, val := range data[dlen-last:] {
|
||||||
|
if int(val) != last {
|
||||||
|
return nil, IncorrectPasswordError
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return data[:dlen-last], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// EncryptPEMBlock returns a PEM block of the specified type holding the
|
||||||
|
// given DER encoded data encrypted with the specified algorithm and
|
||||||
|
// password according to RFC 1423.
|
||||||
|
//
|
||||||
|
// Deprecated: Legacy PEM encryption as specified in RFC 1423 is insecure by
|
||||||
|
// design. Since it does not authenticate the ciphertext, it is vulnerable to
|
||||||
|
// padding oracle attacks that can let an attacker recover the plaintext.
|
||||||
|
func EncryptPEMBlock(rand io.Reader, blockType string, data, password []byte, alg PEMCipher) (*pem.Block, error) {
|
||||||
|
ciph := cipherByKey(alg)
|
||||||
|
if ciph == nil {
|
||||||
|
return nil, errors.New("x509: unknown encryption mode")
|
||||||
|
}
|
||||||
|
iv := make([]byte, ciph.blockSize)
|
||||||
|
if _, err := io.ReadFull(rand, iv); err != nil {
|
||||||
|
return nil, errors.New("x509: cannot generate IV: " + err.Error())
|
||||||
|
}
|
||||||
|
// The salt is the first 8 bytes of the initialization vector,
|
||||||
|
// matching the key derivation in DecryptPEMBlock.
|
||||||
|
key := ciph.deriveKey(password, iv[:8])
|
||||||
|
block, err := ciph.cipherFunc(key)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
enc := cipher.NewCBCEncrypter(block, iv)
|
||||||
|
pad := ciph.blockSize - len(data)%ciph.blockSize
|
||||||
|
encrypted := make([]byte, len(data), len(data)+pad)
|
||||||
|
// We could save this copy by encrypting all the whole blocks in
|
||||||
|
// the data separately, but it doesn't seem worth the additional
|
||||||
|
// code.
|
||||||
|
copy(encrypted, data)
|
||||||
|
// See RFC 1423, Section 1.1.
|
||||||
|
for i := 0; i < pad; i++ {
|
||||||
|
encrypted = append(encrypted, byte(pad))
|
||||||
|
}
|
||||||
|
enc.CryptBlocks(encrypted, encrypted)
|
||||||
|
|
||||||
|
return &pem.Block{
|
||||||
|
Type: blockType,
|
||||||
|
Headers: map[string]string{
|
||||||
|
"Proc-Type": "4,ENCRYPTED",
|
||||||
|
"DEK-Info": ciph.name + "," + hex.EncodeToString(iv),
|
||||||
|
},
|
||||||
|
Bytes: encrypted,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func cipherByName(name string) *rfc1423Algo {
|
||||||
|
for i := range rfc1423Algos {
|
||||||
|
alg := &rfc1423Algos[i]
|
||||||
|
if alg.name == strings.ToUpper(name) {
|
||||||
|
return alg
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func cipherByKey(key PEMCipher) *rfc1423Algo {
|
||||||
|
for i := range rfc1423Algos {
|
||||||
|
alg := &rfc1423Algos[i]
|
||||||
|
if alg.cipher == key {
|
||||||
|
return alg
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
271
smx509/pem_decrypt_test.go
Normal file
271
smx509/pem_decrypt_test.go
Normal file
@ -0,0 +1,271 @@
|
|||||||
|
// Copyright 2012 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package smx509
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"crypto/rand"
|
||||||
|
"crypto/x509"
|
||||||
|
"encoding/base64"
|
||||||
|
"encoding/pem"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestDecrypt(t *testing.T) {
|
||||||
|
for i, data := range testData {
|
||||||
|
t.Logf("test %v. %v", i, data.kind)
|
||||||
|
block, rest := pem.Decode(data.pemData)
|
||||||
|
if len(rest) > 0 {
|
||||||
|
t.Error("extra data")
|
||||||
|
}
|
||||||
|
der, err := DecryptPEMBlock(block, data.password)
|
||||||
|
if err != nil {
|
||||||
|
t.Error("decrypt failed: ", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if _, err := x509.ParsePKCS1PrivateKey(der); err != nil {
|
||||||
|
t.Error("invalid private key: ", err)
|
||||||
|
}
|
||||||
|
plainDER, err := base64.StdEncoding.DecodeString(data.plainDER)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("cannot decode test DER data: ", err)
|
||||||
|
}
|
||||||
|
if !bytes.Equal(der, plainDER) {
|
||||||
|
t.Error("data mismatch")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEncrypt(t *testing.T) {
|
||||||
|
for i, data := range testData {
|
||||||
|
t.Logf("test %v. %v", i, data.kind)
|
||||||
|
plainDER, err := base64.StdEncoding.DecodeString(data.plainDER)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("cannot decode test DER data: ", err)
|
||||||
|
}
|
||||||
|
password := []byte("kremvax1")
|
||||||
|
block, err := EncryptPEMBlock(rand.Reader, "RSA PRIVATE KEY", plainDER, password, data.kind)
|
||||||
|
if err != nil {
|
||||||
|
t.Error("encrypt: ", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if !IsEncryptedPEMBlock(block) {
|
||||||
|
t.Error("PEM block does not appear to be encrypted")
|
||||||
|
}
|
||||||
|
if block.Type != "RSA PRIVATE KEY" {
|
||||||
|
t.Errorf("unexpected block type; got %q want %q", block.Type, "RSA PRIVATE KEY")
|
||||||
|
}
|
||||||
|
if block.Headers["Proc-Type"] != "4,ENCRYPTED" {
|
||||||
|
t.Errorf("block does not have correct Proc-Type header")
|
||||||
|
}
|
||||||
|
der, err := DecryptPEMBlock(block, password)
|
||||||
|
if err != nil {
|
||||||
|
t.Error("decrypt: ", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if !bytes.Equal(der, plainDER) {
|
||||||
|
t.Errorf("data mismatch")
|
||||||
|
}
|
||||||
|
pemContent := string(pem.EncodeToMemory(block))
|
||||||
|
fmt.Printf("%s\n", pemContent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var testData = []struct {
|
||||||
|
kind PEMCipher
|
||||||
|
password []byte
|
||||||
|
pemData []byte
|
||||||
|
plainDER string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
kind: PEMCipherDES,
|
||||||
|
password: []byte("asdf"),
|
||||||
|
pemData: []byte(testingKey(`
|
||||||
|
-----BEGIN RSA TESTING KEY-----
|
||||||
|
Proc-Type: 4,ENCRYPTED
|
||||||
|
DEK-Info: DES-CBC,34F09A4FC8DE22B5
|
||||||
|
WXxy8kbZdiZvANtKvhmPBLV7eVFj2A5z6oAxvI9KGyhG0ZK0skfnt00C24vfU7m5
|
||||||
|
ICXeoqP67lzJ18xCzQfHjDaBNs53DSDT+Iz4e8QUep1xQ30+8QKX2NA2coee3nwc
|
||||||
|
6oM1cuvhNUDemBH2i3dKgMVkfaga0zQiiOq6HJyGSncCMSruQ7F9iWEfRbFcxFCx
|
||||||
|
qtHb1kirfGKEtgWTF+ynyco6+2gMXNu70L7nJcnxnV/RLFkHt7AUU1yrclxz7eZz
|
||||||
|
XOH9VfTjb52q/I8Suozq9coVQwg4tXfIoYUdT//O+mB7zJb9HI9Ps77b9TxDE6Gm
|
||||||
|
4C9brwZ3zg2vqXcwwV6QRZMtyll9rOpxkbw6NPlpfBqkc3xS51bbxivbO/Nve4KD
|
||||||
|
r12ymjFNF4stXCfJnNqKoZ50BHmEEUDu5Wb0fpVn82XrGw7CYc4iug==
|
||||||
|
-----END RSA TESTING KEY-----`)),
|
||||||
|
plainDER: `
|
||||||
|
MIIBPAIBAAJBAPASZe+tCPU6p80AjHhDkVsLYa51D35e/YGa8QcZyooeZM8EHozo
|
||||||
|
KD0fNiKI+53bHdy07N+81VQ8/ejPcRoXPlsCAwEAAQJBAMTxIuSq27VpR+zZ7WJf
|
||||||
|
c6fvv1OBvpMZ0/d1pxL/KnOAgq2rD5hDtk9b0LGhTPgQAmrrMTKuSeGoIuYE+gKQ
|
||||||
|
QvkCIQD+GC1m+/do+QRurr0uo46Kx1LzLeSCrjBk34wiOp2+dwIhAPHfTLRXS2fv
|
||||||
|
7rljm0bYa4+eDZpz+E8RcXEgzhhvcQQ9AiAI5eHZJGOyml3MXnQjiPi55WcDOw0w
|
||||||
|
glcRgT6QCEtz2wIhANSyqaFtosIkHKqrDUGfz/bb5tqMYTAnBruVPaf/WEOBAiEA
|
||||||
|
9xORWeRG1tRpso4+dYy4KdDkuLPIO01KY6neYGm3BCM=`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
kind: PEMCipher3DES,
|
||||||
|
password: []byte("asdf"),
|
||||||
|
pemData: []byte(testingKey(`
|
||||||
|
-----BEGIN RSA TESTING KEY-----
|
||||||
|
Proc-Type: 4,ENCRYPTED
|
||||||
|
DEK-Info: DES-EDE3-CBC,C1F4A6A03682C2C7
|
||||||
|
0JqVdBEH6iqM7drTkj+e2W/bE3LqakaiWhb9WUVonFkhyu8ca/QzebY3b5gCvAZQ
|
||||||
|
YwBvDcT/GHospKqPx+cxDHJNsUASDZws6bz8ZXWJGwZGExKzr0+Qx5fgXn44Ms3x
|
||||||
|
8g1ENFuTXtxo+KoNK0zuAMAqp66Llcds3Fjl4XR18QaD0CrVNAfOdgATWZm5GJxk
|
||||||
|
Fgx5f84nT+/ovvreG+xeOzWgvtKo0UUZVrhGOgfKLpa57adumcJ6SkUuBtEFpZFB
|
||||||
|
ldw5w7WC7d13x2LsRkwo8ZrDKgIV+Y9GNvhuCCkTzNP0V3gNeJpd201HZHR+9n3w
|
||||||
|
3z0VjR/MGqsfcy1ziEWMNOO53At3zlG6zP05aHMnMcZoVXadEK6L1gz++inSSDCq
|
||||||
|
gI0UJP4e3JVB7AkgYymYAwiYALAkoEIuanxoc50njJk=
|
||||||
|
-----END RSA TESTING KEY-----`)),
|
||||||
|
plainDER: `
|
||||||
|
MIIBOwIBAAJBANOCXKdoNS/iP/MAbl9cf1/SF3P+Ns7ZeNL27CfmDh0O6Zduaax5
|
||||||
|
NBiumd2PmjkaCu7lQ5JOibHfWn+xJsc3kw0CAwEAAQJANX/W8d1Q/sCqzkuAn4xl
|
||||||
|
B5a7qfJWaLHndu1QRLNTRJPn0Ee7OKJ4H0QKOhQM6vpjRrz+P2u9thn6wUxoPsef
|
||||||
|
QQIhAP/jCkfejFcy4v15beqKzwz08/tslVjF+Yq41eJGejmxAiEA05pMoqfkyjcx
|
||||||
|
fyvGhpoOyoCp71vSGUfR2I9CR65oKh0CIC1Msjs66LlfJtQctRq6bCEtFCxEcsP+
|
||||||
|
eEjYo/Sk6WphAiEAxpgWPMJeU/shFT28gS+tmhjPZLpEoT1qkVlC14u0b3ECIQDX
|
||||||
|
tZZZxCtPAm7shftEib0VU77Lk8MsXJcx2C4voRsjEw==`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
kind: PEMCipherAES128,
|
||||||
|
password: []byte("asdf"),
|
||||||
|
pemData: []byte(testingKey(`
|
||||||
|
-----BEGIN RSA TESTING KEY-----
|
||||||
|
Proc-Type: 4,ENCRYPTED
|
||||||
|
DEK-Info: AES-128-CBC,D4492E793FC835CC038A728ED174F78A
|
||||||
|
EyfQSzXSjv6BaNH+NHdXRlkHdimpF9izWlugVJAPApgXrq5YldPe2aGIOFXyJ+QE
|
||||||
|
ZIG20DYqaPzJRjTEbPNZ6Es0S2JJ5yCpKxwJuDkgJZKtF39Q2i36JeGbSZQIuWJE
|
||||||
|
GZbBpf1jDH/pr0iGonuAdl2PCCZUiy+8eLsD2tyviHUkFLOB+ykYoJ5t8ngZ/B6D
|
||||||
|
33U43LLb7+9zD4y3Q9OVHqBFGyHcxCY9+9Qh4ZnFp7DTf6RY5TNEvE3s4g6aDpBs
|
||||||
|
3NbvRVvYTgs8K9EPk4K+5R+P2kD8J8KvEIGxVa1vz8QoCJ/jr7Ka2rvNgPCex5/E
|
||||||
|
080LzLHPCrXKdlr/f50yhNWq08ZxMWQFkui+FDHPDUaEELKAXV8/5PDxw80Rtybo
|
||||||
|
AVYoCVIbZXZCuCO81op8UcOgEpTtyU5Lgh3Mw5scQL0=
|
||||||
|
-----END RSA TESTING KEY-----`)),
|
||||||
|
plainDER: `
|
||||||
|
MIIBOgIBAAJBAMBlj5FxYtqbcy8wY89d/S7n0+r5MzD9F63BA/Lpl78vQKtdJ5dT
|
||||||
|
cDGh/rBt1ufRrNp0WihcmZi7Mpl/3jHjiWECAwEAAQJABNOHYnKhtDIqFYj1OAJ3
|
||||||
|
k3GlU0OlERmIOoeY/cL2V4lgwllPBEs7r134AY4wMmZSBUj8UR/O4SNO668ElKPE
|
||||||
|
cQIhAOuqY7/115x5KCdGDMWi+jNaMxIvI4ETGwV40ykGzqlzAiEA0P9oEC3m9tHB
|
||||||
|
kbpjSTxaNkrXxDgdEOZz8X0uOUUwHNsCIAwzcSCiGLyYJTULUmP1ESERfW1mlV78
|
||||||
|
XzzESaJpIM/zAiBQkSTcl9VhcJreQqvjn5BnPZLP4ZHS4gPwJAGdsj5J4QIhAOVR
|
||||||
|
B3WlRNTXR2WsJ5JdByezg9xzdXzULqmga0OE339a`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
kind: PEMCipherAES192,
|
||||||
|
password: []byte("asdf"),
|
||||||
|
pemData: []byte(testingKey(`
|
||||||
|
-----BEGIN RSA TESTING KEY-----
|
||||||
|
Proc-Type: 4,ENCRYPTED
|
||||||
|
DEK-Info: AES-192-CBC,E2C9FB02BCA23ADE1829F8D8BC5F5369
|
||||||
|
cqVslvHqDDM6qwU6YjezCRifXmKsrgEev7ng6Qs7UmDJOpHDgJQZI9fwMFUhIyn5
|
||||||
|
FbCu1SHkLMW52Ld3CuEqMnzWMlhPrW8tFvUOrMWPYSisv7nNq88HobZEJcUNL2MM
|
||||||
|
Y15XmHW6IJwPqhKyLHpWXyOCVEh4ODND2nV15PCoi18oTa475baxSk7+1qH7GuIs
|
||||||
|
Rb7tshNTMqHbCpyo9Rn3UxeFIf9efdl8YLiMoIqc7J8E5e9VlbeQSdLMQOgDAQJG
|
||||||
|
ReUtTw8exmKsY4gsSjhkg5uiw7/ZB1Ihto0qnfQJgjGc680qGkT1d6JfvOfeYAk6
|
||||||
|
xn5RqS/h8rYAYm64KnepfC9vIujo4NqpaREDmaLdX5MJPQ+SlytITQvgUsUq3q/t
|
||||||
|
Ss85xjQEZH3hzwjQqdJvmA4hYP6SUjxYpBM+02xZ1Xw=
|
||||||
|
-----END RSA TESTING KEY-----`)),
|
||||||
|
plainDER: `
|
||||||
|
MIIBOwIBAAJBAMGcRrZiNNmtF20zyS6MQ7pdGx17aFDl+lTl+qnLuJRUCMUG05xs
|
||||||
|
OmxmL/O1Qlf+bnqR8Bgg65SfKg21SYuLhiMCAwEAAQJBAL94uuHyO4wux2VC+qpj
|
||||||
|
IzPykjdU7XRcDHbbvksf4xokSeUFjjD3PB0Qa83M94y89ZfdILIqS9x5EgSB4/lX
|
||||||
|
qNkCIQD6cCIqLfzq/lYbZbQgAAjpBXeQVYsbvVtJrPrXJAlVVQIhAMXpDKMeFPMn
|
||||||
|
J0g2rbx1gngx0qOa5r5iMU5w/noN4W2XAiBjf+WzCG5yFvazD+dOx3TC0A8+4x3P
|
||||||
|
uZ3pWbaXf5PNuQIgAcdXarvhelH2w2piY1g3BPeFqhzBSCK/yLGxR82KIh8CIQDD
|
||||||
|
+qGKsd09NhQ/G27y/DARzOYtml1NvdmCQAgsDIIOLA==`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
kind: PEMCipherAES256,
|
||||||
|
password: []byte("asdf"),
|
||||||
|
pemData: []byte(testingKey(`
|
||||||
|
-----BEGIN RSA TESTING KEY-----
|
||||||
|
Proc-Type: 4,ENCRYPTED
|
||||||
|
DEK-Info: AES-256-CBC,8E7ED5CD731902CE938957A886A5FFBD
|
||||||
|
4Mxr+KIzRVwoOP0wwq6caSkvW0iS+GE2h2Ov/u+n9ZTMwL83PRnmjfjzBgfRZLVf
|
||||||
|
JFPXxUK26kMNpIdssNnqGOds+DhB+oSrsNKoxgxSl5OBoYv9eJTVYm7qOyAFIsjr
|
||||||
|
DRKAcjYCmzfesr7PVTowwy0RtHmYwyXMGDlAzzZrEvaiySFFmMyKKvtoavwaFoc7
|
||||||
|
Pz3RZScwIuubzTGJ1x8EzdffYOsdCa9Mtgpp3L136+23dOd6L/qK2EG2fzrJSHs/
|
||||||
|
2XugkleBFSMKzEp9mxXKRfa++uidQvMZTFLDK9w5YjrRvMBo/l2BoZIsq0jAIE1N
|
||||||
|
sv5Z/KwlX+3MDEpPQpUwGPlGGdLnjI3UZ+cjgqBcoMiNc6HfgbBgYJSU6aDSHuCk
|
||||||
|
clCwByxWkBNgJ2GrkwNrF26v+bGJJJNR4SKouY1jQf0=
|
||||||
|
-----END RSA TESTING KEY-----`)),
|
||||||
|
plainDER: `
|
||||||
|
MIIBOgIBAAJBAKy3GFkstoCHIEeUU/qO8207m8WSrjksR+p9B4tf1w5k+2O1V/GY
|
||||||
|
AQ5WFCApItcOkQe/I0yZZJk/PmCqMzSxrc8CAwEAAQJAOCAz0F7AW9oNelVQSP8F
|
||||||
|
Sfzx7O1yom+qWyAQQJF/gFR11gpf9xpVnnyu1WxIRnDUh1LZwUsjwlDYb7MB74id
|
||||||
|
oQIhANPcOiLwOPT4sIUpRM5HG6BF1BI7L77VpyGVk8xNP7X/AiEA0LMHZtk4I+lJ
|
||||||
|
nClgYp4Yh2JZ1Znbu7IoQMCEJCjwKDECIGd8Dzm5tViTkUW6Hs3Tlf73nNs65duF
|
||||||
|
aRnSglss8I3pAiEAonEnKruawgD8RavDFR+fUgmQiPz4FnGGeVgfwpGG1JECIBYq
|
||||||
|
PXHYtPqxQIbD2pScR5qum7iGUh11lEUPkmt+2uqS`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
kind: PEMCipherSM4,
|
||||||
|
password: []byte("asdf"),
|
||||||
|
pemData: []byte(testingKey(`
|
||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
Proc-Type: 4,ENCRYPTED
|
||||||
|
DEK-Info: sm4-cbc,4cf10431aa24f6a4c1490ce93ff086ef
|
||||||
|
|
||||||
|
OSUW2Zbd7E+MKulT70SpQIsR0FdV1MP41OKvxT3XfOMZDk3naDyJoBFon8FEftlN
|
||||||
|
xKNkRnzZTmzteRzySbNQBKIwwHnak8Vcqwy5UB61+RWC5rk+kDRiwG6sZp6HFs4Z
|
||||||
|
GLrzVQlh6Ag/ecckhms0FfLbmKLeCwG1MlLaI8ZHvZSQ5R1JPdF43rmxkoA6RTg+
|
||||||
|
SWWf2T5T3DyOOPmgaxrRQJZURJuJZK3eyAvU395t1xDsvdgOIQlmgEA6nmrNcJQt
|
||||||
|
cn88qJ6NpRpVjdDupnOynJ726diIcugYwLcxhMir5eSNkMkjR5SZdEwuFgcbicvc
|
||||||
|
TkCGwp6aSyLYpHsIwTJupY8Lk32WuqpC34K/IJlNDichVyeLILEj9GqUGJNm/1N3
|
||||||
|
FKMobhAYj14+AsMKzR+4rOsYeJxX+8ws3D5RbL7nTKs=
|
||||||
|
-----END RSA PRIVATE KEY-----`)),
|
||||||
|
plainDER: `
|
||||||
|
MIIBOgIBAAJBAMBlj5FxYtqbcy8wY89d/S7n0+r5MzD9F63BA/Lpl78vQKtdJ5dT
|
||||||
|
cDGh/rBt1ufRrNp0WihcmZi7Mpl/3jHjiWECAwEAAQJABNOHYnKhtDIqFYj1OAJ3
|
||||||
|
k3GlU0OlERmIOoeY/cL2V4lgwllPBEs7r134AY4wMmZSBUj8UR/O4SNO668ElKPE
|
||||||
|
cQIhAOuqY7/115x5KCdGDMWi+jNaMxIvI4ETGwV40ykGzqlzAiEA0P9oEC3m9tHB
|
||||||
|
kbpjSTxaNkrXxDgdEOZz8X0uOUUwHNsCIAwzcSCiGLyYJTULUmP1ESERfW1mlV78
|
||||||
|
XzzESaJpIM/zAiBQkSTcl9VhcJreQqvjn5BnPZLP4ZHS4gPwJAGdsj5J4QIhAOVR
|
||||||
|
B3WlRNTXR2WsJ5JdByezg9xzdXzULqmga0OE339a`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// generated with:
|
||||||
|
// openssl genrsa -aes128 -passout pass:asdf -out server.orig.key 128
|
||||||
|
kind: PEMCipherAES128,
|
||||||
|
password: []byte("asdf"),
|
||||||
|
pemData: []byte(testingKey(`
|
||||||
|
-----BEGIN RSA TESTING KEY-----
|
||||||
|
Proc-Type: 4,ENCRYPTED
|
||||||
|
DEK-Info: AES-128-CBC,74611ABC2571AF11B1BF9B69E62C89E7
|
||||||
|
6ei/MlytjE0FFgZOGQ+jrwomKfpl8kdefeE0NSt/DMRrw8OacHAzBNi3pPEa0eX3
|
||||||
|
eND9l7C9meCirWovjj9QWVHrXyugFuDIqgdhQ8iHTgCfF3lrmcttVrbIfMDw+smD
|
||||||
|
hTP8O1mS/MHl92NE0nhv0w==
|
||||||
|
-----END RSA TESTING KEY-----`)),
|
||||||
|
plainDER: `
|
||||||
|
MGMCAQACEQC6ssxmYuauuHGOCDAI54RdAgMBAAECEQCWIn6Yv2O+kBcDF7STctKB
|
||||||
|
AgkA8SEfu/2i3g0CCQDGNlXbBHX7kQIIK3Ww5o0cYbECCQDCimPb0dYGsQIIeQ7A
|
||||||
|
jryIst8=`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var incompleteBlockPEM = testingKey(`
|
||||||
|
-----BEGIN RSA TESTING KEY-----
|
||||||
|
Proc-Type: 4,ENCRYPTED
|
||||||
|
DEK-Info: AES-128-CBC,74611ABC2571AF11B1BF9B69E62C89E7
|
||||||
|
6L8yXK2MTQUWBk4ZD6OvCiYp+mXyR1594TQ1K38MxGvDw5pwcDME2Lek8RrR5fd40P2XsL2Z4KKt
|
||||||
|
ai+OP1BZUetfK6AW4MiqB2FDyIdOAJ8XeWuZy21Wtsh8wPD6yYOFM/w7WZL8weX3Y0TSeG/T
|
||||||
|
-----END RSA TESTING KEY-----`)
|
||||||
|
|
||||||
|
func TestIncompleteBlock(t *testing.T) {
|
||||||
|
// incompleteBlockPEM contains ciphertext that is not a multiple of the
|
||||||
|
// block size. This previously panicked. See #11215.
|
||||||
|
block, _ := pem.Decode([]byte(incompleteBlockPEM))
|
||||||
|
_, err := DecryptPEMBlock(block, []byte("foo"))
|
||||||
|
if err == nil {
|
||||||
|
t.Fatal("Bad PEM data decrypted successfully")
|
||||||
|
}
|
||||||
|
const expectedSubstr = "block size"
|
||||||
|
if e := err.Error(); !strings.Contains(e, expectedSubstr) {
|
||||||
|
t.Fatalf("Expected error containing %q but got: %q", expectedSubstr, e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testingKey(s string) string { return strings.ReplaceAll(s, "TESTING KEY", "PRIVATE KEY") }
|
Loading…
x
Reference in New Issue
Block a user