github.com/amanya/packer@v0.12.1-0.20161117214323-902ac5ab2eb6/builder/azure/pkcs12/crypto.go (about) 1 // implementation of https://tools.ietf.org/html/rfc2898#section-6.1.2 2 3 package pkcs12 4 5 import ( 6 "bytes" 7 "crypto/cipher" 8 "crypto/des" 9 "crypto/rand" 10 "crypto/x509/pkix" 11 "encoding/asn1" 12 "errors" 13 "io" 14 15 "github.com/mitchellh/packer/builder/azure/pkcs12/rc2" 16 ) 17 18 const ( 19 pbeWithSHAAnd3KeyTripleDESCBC = "pbeWithSHAAnd3-KeyTripleDES-CBC" 20 pbewithSHAAnd40BitRC2CBC = "pbewithSHAAnd40BitRC2-CBC" 21 ) 22 23 const ( 24 pbeIterationCount = 2048 25 pbeSaltSizeBytes = 8 26 ) 27 28 var ( 29 oidPbeWithSHAAnd3KeyTripleDESCBC = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 12, 1, 3} 30 oidPbewithSHAAnd40BitRC2CBC = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 12, 1, 6} 31 ) 32 33 var algByOID = map[string]string{ 34 oidPbeWithSHAAnd3KeyTripleDESCBC.String(): pbeWithSHAAnd3KeyTripleDESCBC, 35 oidPbewithSHAAnd40BitRC2CBC.String(): pbewithSHAAnd40BitRC2CBC, 36 } 37 38 var blockcodeByAlg = map[string]func(key []byte) (cipher.Block, error){ 39 pbeWithSHAAnd3KeyTripleDESCBC: des.NewTripleDESCipher, 40 pbewithSHAAnd40BitRC2CBC: func(key []byte) (cipher.Block, error) { 41 return rc2.New(key, len(key)*8) 42 }, 43 } 44 45 type pbeParams struct { 46 Salt []byte 47 Iterations int 48 } 49 50 func pad(src []byte, blockSize int) []byte { 51 paddingLength := blockSize - len(src)%blockSize 52 paddingText := bytes.Repeat([]byte{byte(paddingLength)}, paddingLength) 53 return append(src, paddingText...) 54 } 55 56 func pbEncrypt(plainText, salt, password []byte, iterations int) (cipherText []byte, err error) { 57 _, err = io.ReadFull(rand.Reader, salt) 58 if err != nil { 59 return nil, errors.New("pkcs12: failed to create a random salt value: " + err.Error()) 60 } 61 62 key := deriveKeyByAlg[pbeWithSHAAnd3KeyTripleDESCBC](salt, password, iterations) 63 iv := deriveIVByAlg[pbeWithSHAAnd3KeyTripleDESCBC](salt, password, iterations) 64 65 block, err := des.NewTripleDESCipher(key) 66 if err != nil { 67 return nil, errors.New("pkcs12: failed to create a block cipher: " + err.Error()) 68 } 69 70 paddedPlainText := pad(plainText, block.BlockSize()) 71 72 encrypter := cipher.NewCBCEncrypter(block, iv) 73 cipherText = make([]byte, len(paddedPlainText)) 74 encrypter.CryptBlocks(cipherText, paddedPlainText) 75 76 return cipherText, nil 77 } 78 79 type decryptable interface { 80 GetAlgorithm() pkix.AlgorithmIdentifier 81 GetData() []byte 82 }