83 lines
2.2 KiB
Go
83 lines
2.2 KiB
Go
// implementation of https://tools.ietf.org/html/rfc2898#section-6.1.2
|
|
|
|
package pkcs12
|
|
|
|
import (
|
|
"bytes"
|
|
"crypto/cipher"
|
|
"crypto/des"
|
|
"crypto/rand"
|
|
"crypto/x509/pkix"
|
|
"encoding/asn1"
|
|
"errors"
|
|
"io"
|
|
|
|
"github.com/mitchellh/packer/builder/azure/pkcs12/rc2"
|
|
)
|
|
|
|
const (
|
|
pbeWithSHAAnd3KeyTripleDESCBC = "pbeWithSHAAnd3-KeyTripleDES-CBC"
|
|
pbewithSHAAnd40BitRC2CBC = "pbewithSHAAnd40BitRC2-CBC"
|
|
)
|
|
|
|
const (
|
|
pbeIterationCount = 2048
|
|
pbeSaltSizeBytes = 8
|
|
)
|
|
|
|
var (
|
|
oidPbeWithSHAAnd3KeyTripleDESCBC = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 12, 1, 3}
|
|
oidPbewithSHAAnd40BitRC2CBC = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 12, 1, 6}
|
|
)
|
|
|
|
var algByOID = map[string]string{
|
|
oidPbeWithSHAAnd3KeyTripleDESCBC.String(): pbeWithSHAAnd3KeyTripleDESCBC,
|
|
oidPbewithSHAAnd40BitRC2CBC.String(): pbewithSHAAnd40BitRC2CBC,
|
|
}
|
|
|
|
var blockcodeByAlg = map[string]func(key []byte) (cipher.Block, error){
|
|
pbeWithSHAAnd3KeyTripleDESCBC: des.NewTripleDESCipher,
|
|
pbewithSHAAnd40BitRC2CBC: func(key []byte) (cipher.Block, error) {
|
|
return rc2.New(key, len(key)*8)
|
|
},
|
|
}
|
|
|
|
type pbeParams struct {
|
|
Salt []byte
|
|
Iterations int
|
|
}
|
|
|
|
func pad(src []byte, blockSize int) []byte {
|
|
paddingLength := blockSize - len(src)%blockSize
|
|
paddingText := bytes.Repeat([]byte{byte(paddingLength)}, paddingLength)
|
|
return append(src, paddingText...)
|
|
}
|
|
|
|
func pbEncrypt(plainText, salt, password []byte, iterations int) (cipherText []byte, err error) {
|
|
_, err = io.ReadFull(rand.Reader, salt)
|
|
if err != nil {
|
|
return nil, errors.New("pkcs12: failed to create a random salt value: " + err.Error())
|
|
}
|
|
|
|
key := deriveKeyByAlg[pbeWithSHAAnd3KeyTripleDESCBC](salt, password, iterations)
|
|
iv := deriveIVByAlg[pbeWithSHAAnd3KeyTripleDESCBC](salt, password, iterations)
|
|
|
|
block, err := des.NewTripleDESCipher(key)
|
|
if err != nil {
|
|
return nil, errors.New("pkcs12: failed to create a block cipher: " + err.Error())
|
|
}
|
|
|
|
paddedPlainText := pad(plainText, block.BlockSize())
|
|
|
|
encrypter := cipher.NewCBCEncrypter(block, iv)
|
|
cipherText = make([]byte, len(paddedPlainText))
|
|
encrypter.CryptBlocks(cipherText, paddedPlainText)
|
|
|
|
return cipherText, nil
|
|
}
|
|
|
|
type decryptable interface {
|
|
GetAlgorithm() pkix.AlgorithmIdentifier
|
|
GetData() []byte
|
|
}
|