Home | History | Annotate | Download | only in x509
      1 // Copyright 2012 The Go Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style
      3 // license that can be found in the LICENSE file.
      4 
      5 package x509
      6 
      7 import (
      8 	"bytes"
      9 	"crypto/rand"
     10 	"encoding/base64"
     11 	"encoding/pem"
     12 	"strings"
     13 	"testing"
     14 )
     15 
     16 func TestDecrypt(t *testing.T) {
     17 	for i, data := range testData {
     18 		t.Logf("test %v. %v", i, data.kind)
     19 		block, rest := pem.Decode(data.pemData)
     20 		if len(rest) > 0 {
     21 			t.Error("extra data")
     22 		}
     23 		der, err := DecryptPEMBlock(block, data.password)
     24 		if err != nil {
     25 			t.Error("decrypt failed: ", err)
     26 			continue
     27 		}
     28 		if _, err := ParsePKCS1PrivateKey(der); err != nil {
     29 			t.Error("invalid private key: ", err)
     30 		}
     31 		plainDER, err := base64.StdEncoding.DecodeString(data.plainDER)
     32 		if err != nil {
     33 			t.Fatal("cannot decode test DER data: ", err)
     34 		}
     35 		if !bytes.Equal(der, plainDER) {
     36 			t.Error("data mismatch")
     37 		}
     38 	}
     39 }
     40 
     41 func TestEncrypt(t *testing.T) {
     42 	for i, data := range testData {
     43 		t.Logf("test %v. %v", i, data.kind)
     44 		plainDER, err := base64.StdEncoding.DecodeString(data.plainDER)
     45 		if err != nil {
     46 			t.Fatal("cannot decode test DER data: ", err)
     47 		}
     48 		password := []byte("kremvax1")
     49 		block, err := EncryptPEMBlock(rand.Reader, "RSA PRIVATE KEY", plainDER, password, data.kind)
     50 		if err != nil {
     51 			t.Error("encrypt: ", err)
     52 			continue
     53 		}
     54 		if !IsEncryptedPEMBlock(block) {
     55 			t.Error("PEM block does not appear to be encrypted")
     56 		}
     57 		if block.Type != "RSA PRIVATE KEY" {
     58 			t.Errorf("unexpected block type; got %q want %q", block.Type, "RSA PRIVATE KEY")
     59 		}
     60 		if block.Headers["Proc-Type"] != "4,ENCRYPTED" {
     61 			t.Errorf("block does not have correct Proc-Type header")
     62 		}
     63 		der, err := DecryptPEMBlock(block, password)
     64 		if err != nil {
     65 			t.Error("decrypt: ", err)
     66 			continue
     67 		}
     68 		if !bytes.Equal(der, plainDER) {
     69 			t.Errorf("data mismatch")
     70 		}
     71 	}
     72 }
     73 
     74 var testData = []struct {
     75 	kind     PEMCipher
     76 	password []byte
     77 	pemData  []byte
     78 	plainDER string
     79 }{
     80 	{
     81 		kind:     PEMCipherDES,
     82 		password: []byte("asdf"),
     83 		pemData: []byte(`
     84 -----BEGIN RSA PRIVATE KEY-----
     85 Proc-Type: 4,ENCRYPTED
     86 DEK-Info: DES-CBC,34F09A4FC8DE22B5
     87 
     88 WXxy8kbZdiZvANtKvhmPBLV7eVFj2A5z6oAxvI9KGyhG0ZK0skfnt00C24vfU7m5
     89 ICXeoqP67lzJ18xCzQfHjDaBNs53DSDT+Iz4e8QUep1xQ30+8QKX2NA2coee3nwc
     90 6oM1cuvhNUDemBH2i3dKgMVkfaga0zQiiOq6HJyGSncCMSruQ7F9iWEfRbFcxFCx
     91 qtHb1kirfGKEtgWTF+ynyco6+2gMXNu70L7nJcnxnV/RLFkHt7AUU1yrclxz7eZz
     92 XOH9VfTjb52q/I8Suozq9coVQwg4tXfIoYUdT//O+mB7zJb9HI9Ps77b9TxDE6Gm
     93 4C9brwZ3zg2vqXcwwV6QRZMtyll9rOpxkbw6NPlpfBqkc3xS51bbxivbO/Nve4KD
     94 r12ymjFNF4stXCfJnNqKoZ50BHmEEUDu5Wb0fpVn82XrGw7CYc4iug==
     95 -----END RSA PRIVATE KEY-----`),
     96 		plainDER: `
     97 MIIBPAIBAAJBAPASZe+tCPU6p80AjHhDkVsLYa51D35e/YGa8QcZyooeZM8EHozo
     98 KD0fNiKI+53bHdy07N+81VQ8/ejPcRoXPlsCAwEAAQJBAMTxIuSq27VpR+zZ7WJf
     99 c6fvv1OBvpMZ0/d1pxL/KnOAgq2rD5hDtk9b0LGhTPgQAmrrMTKuSeGoIuYE+gKQ
    100 QvkCIQD+GC1m+/do+QRurr0uo46Kx1LzLeSCrjBk34wiOp2+dwIhAPHfTLRXS2fv
    101 7rljm0bYa4+eDZpz+E8RcXEgzhhvcQQ9AiAI5eHZJGOyml3MXnQjiPi55WcDOw0w
    102 glcRgT6QCEtz2wIhANSyqaFtosIkHKqrDUGfz/bb5tqMYTAnBruVPaf/WEOBAiEA
    103 9xORWeRG1tRpso4+dYy4KdDkuLPIO01KY6neYGm3BCM=`,
    104 	},
    105 	{
    106 		kind:     PEMCipher3DES,
    107 		password: []byte("asdf"),
    108 		pemData: []byte(`
    109 -----BEGIN RSA PRIVATE KEY-----
    110 Proc-Type: 4,ENCRYPTED
    111 DEK-Info: DES-EDE3-CBC,C1F4A6A03682C2C7
    112 
    113 0JqVdBEH6iqM7drTkj+e2W/bE3LqakaiWhb9WUVonFkhyu8ca/QzebY3b5gCvAZQ
    114 YwBvDcT/GHospKqPx+cxDHJNsUASDZws6bz8ZXWJGwZGExKzr0+Qx5fgXn44Ms3x
    115 8g1ENFuTXtxo+KoNK0zuAMAqp66Llcds3Fjl4XR18QaD0CrVNAfOdgATWZm5GJxk
    116 Fgx5f84nT+/ovvreG+xeOzWgvtKo0UUZVrhGOgfKLpa57adumcJ6SkUuBtEFpZFB
    117 ldw5w7WC7d13x2LsRkwo8ZrDKgIV+Y9GNvhuCCkTzNP0V3gNeJpd201HZHR+9n3w
    118 3z0VjR/MGqsfcy1ziEWMNOO53At3zlG6zP05aHMnMcZoVXadEK6L1gz++inSSDCq
    119 gI0UJP4e3JVB7AkgYymYAwiYALAkoEIuanxoc50njJk=
    120 -----END RSA PRIVATE KEY-----`),
    121 		plainDER: `
    122 MIIBOwIBAAJBANOCXKdoNS/iP/MAbl9cf1/SF3P+Ns7ZeNL27CfmDh0O6Zduaax5
    123 NBiumd2PmjkaCu7lQ5JOibHfWn+xJsc3kw0CAwEAAQJANX/W8d1Q/sCqzkuAn4xl
    124 B5a7qfJWaLHndu1QRLNTRJPn0Ee7OKJ4H0QKOhQM6vpjRrz+P2u9thn6wUxoPsef
    125 QQIhAP/jCkfejFcy4v15beqKzwz08/tslVjF+Yq41eJGejmxAiEA05pMoqfkyjcx
    126 fyvGhpoOyoCp71vSGUfR2I9CR65oKh0CIC1Msjs66LlfJtQctRq6bCEtFCxEcsP+
    127 eEjYo/Sk6WphAiEAxpgWPMJeU/shFT28gS+tmhjPZLpEoT1qkVlC14u0b3ECIQDX
    128 tZZZxCtPAm7shftEib0VU77Lk8MsXJcx2C4voRsjEw==`,
    129 	},
    130 	{
    131 		kind:     PEMCipherAES128,
    132 		password: []byte("asdf"),
    133 		pemData: []byte(`
    134 -----BEGIN RSA PRIVATE KEY-----
    135 Proc-Type: 4,ENCRYPTED
    136 DEK-Info: AES-128-CBC,D4492E793FC835CC038A728ED174F78A
    137 
    138 EyfQSzXSjv6BaNH+NHdXRlkHdimpF9izWlugVJAPApgXrq5YldPe2aGIOFXyJ+QE
    139 ZIG20DYqaPzJRjTEbPNZ6Es0S2JJ5yCpKxwJuDkgJZKtF39Q2i36JeGbSZQIuWJE
    140 GZbBpf1jDH/pr0iGonuAdl2PCCZUiy+8eLsD2tyviHUkFLOB+ykYoJ5t8ngZ/B6D
    141 33U43LLb7+9zD4y3Q9OVHqBFGyHcxCY9+9Qh4ZnFp7DTf6RY5TNEvE3s4g6aDpBs
    142 3NbvRVvYTgs8K9EPk4K+5R+P2kD8J8KvEIGxVa1vz8QoCJ/jr7Ka2rvNgPCex5/E
    143 080LzLHPCrXKdlr/f50yhNWq08ZxMWQFkui+FDHPDUaEELKAXV8/5PDxw80Rtybo
    144 AVYoCVIbZXZCuCO81op8UcOgEpTtyU5Lgh3Mw5scQL0=
    145 -----END RSA PRIVATE KEY-----`),
    146 		plainDER: `
    147 MIIBOgIBAAJBAMBlj5FxYtqbcy8wY89d/S7n0+r5MzD9F63BA/Lpl78vQKtdJ5dT
    148 cDGh/rBt1ufRrNp0WihcmZi7Mpl/3jHjiWECAwEAAQJABNOHYnKhtDIqFYj1OAJ3
    149 k3GlU0OlERmIOoeY/cL2V4lgwllPBEs7r134AY4wMmZSBUj8UR/O4SNO668ElKPE
    150 cQIhAOuqY7/115x5KCdGDMWi+jNaMxIvI4ETGwV40ykGzqlzAiEA0P9oEC3m9tHB
    151 kbpjSTxaNkrXxDgdEOZz8X0uOUUwHNsCIAwzcSCiGLyYJTULUmP1ESERfW1mlV78
    152 XzzESaJpIM/zAiBQkSTcl9VhcJreQqvjn5BnPZLP4ZHS4gPwJAGdsj5J4QIhAOVR
    153 B3WlRNTXR2WsJ5JdByezg9xzdXzULqmga0OE339a`,
    154 	},
    155 	{
    156 		kind:     PEMCipherAES192,
    157 		password: []byte("asdf"),
    158 		pemData: []byte(`
    159 -----BEGIN RSA PRIVATE KEY-----
    160 Proc-Type: 4,ENCRYPTED
    161 DEK-Info: AES-192-CBC,E2C9FB02BCA23ADE1829F8D8BC5F5369
    162 
    163 cqVslvHqDDM6qwU6YjezCRifXmKsrgEev7ng6Qs7UmDJOpHDgJQZI9fwMFUhIyn5
    164 FbCu1SHkLMW52Ld3CuEqMnzWMlhPrW8tFvUOrMWPYSisv7nNq88HobZEJcUNL2MM
    165 Y15XmHW6IJwPqhKyLHpWXyOCVEh4ODND2nV15PCoi18oTa475baxSk7+1qH7GuIs
    166 Rb7tshNTMqHbCpyo9Rn3UxeFIf9efdl8YLiMoIqc7J8E5e9VlbeQSdLMQOgDAQJG
    167 ReUtTw8exmKsY4gsSjhkg5uiw7/ZB1Ihto0qnfQJgjGc680qGkT1d6JfvOfeYAk6
    168 xn5RqS/h8rYAYm64KnepfC9vIujo4NqpaREDmaLdX5MJPQ+SlytITQvgUsUq3q/t
    169 Ss85xjQEZH3hzwjQqdJvmA4hYP6SUjxYpBM+02xZ1Xw=
    170 -----END RSA PRIVATE KEY-----`),
    171 		plainDER: `
    172 MIIBOwIBAAJBAMGcRrZiNNmtF20zyS6MQ7pdGx17aFDl+lTl+qnLuJRUCMUG05xs
    173 OmxmL/O1Qlf+bnqR8Bgg65SfKg21SYuLhiMCAwEAAQJBAL94uuHyO4wux2VC+qpj
    174 IzPykjdU7XRcDHbbvksf4xokSeUFjjD3PB0Qa83M94y89ZfdILIqS9x5EgSB4/lX
    175 qNkCIQD6cCIqLfzq/lYbZbQgAAjpBXeQVYsbvVtJrPrXJAlVVQIhAMXpDKMeFPMn
    176 J0g2rbx1gngx0qOa5r5iMU5w/noN4W2XAiBjf+WzCG5yFvazD+dOx3TC0A8+4x3P
    177 uZ3pWbaXf5PNuQIgAcdXarvhelH2w2piY1g3BPeFqhzBSCK/yLGxR82KIh8CIQDD
    178 +qGKsd09NhQ/G27y/DARzOYtml1NvdmCQAgsDIIOLA==`,
    179 	},
    180 	{
    181 		kind:     PEMCipherAES256,
    182 		password: []byte("asdf"),
    183 		pemData: []byte(`
    184 -----BEGIN RSA PRIVATE KEY-----
    185 Proc-Type: 4,ENCRYPTED
    186 DEK-Info: AES-256-CBC,8E7ED5CD731902CE938957A886A5FFBD
    187 
    188 4Mxr+KIzRVwoOP0wwq6caSkvW0iS+GE2h2Ov/u+n9ZTMwL83PRnmjfjzBgfRZLVf
    189 JFPXxUK26kMNpIdssNnqGOds+DhB+oSrsNKoxgxSl5OBoYv9eJTVYm7qOyAFIsjr
    190 DRKAcjYCmzfesr7PVTowwy0RtHmYwyXMGDlAzzZrEvaiySFFmMyKKvtoavwaFoc7
    191 Pz3RZScwIuubzTGJ1x8EzdffYOsdCa9Mtgpp3L136+23dOd6L/qK2EG2fzrJSHs/
    192 2XugkleBFSMKzEp9mxXKRfa++uidQvMZTFLDK9w5YjrRvMBo/l2BoZIsq0jAIE1N
    193 sv5Z/KwlX+3MDEpPQpUwGPlGGdLnjI3UZ+cjgqBcoMiNc6HfgbBgYJSU6aDSHuCk
    194 clCwByxWkBNgJ2GrkwNrF26v+bGJJJNR4SKouY1jQf0=
    195 -----END RSA PRIVATE KEY-----`),
    196 		plainDER: `
    197 MIIBOgIBAAJBAKy3GFkstoCHIEeUU/qO8207m8WSrjksR+p9B4tf1w5k+2O1V/GY
    198 AQ5WFCApItcOkQe/I0yZZJk/PmCqMzSxrc8CAwEAAQJAOCAz0F7AW9oNelVQSP8F
    199 Sfzx7O1yom+qWyAQQJF/gFR11gpf9xpVnnyu1WxIRnDUh1LZwUsjwlDYb7MB74id
    200 oQIhANPcOiLwOPT4sIUpRM5HG6BF1BI7L77VpyGVk8xNP7X/AiEA0LMHZtk4I+lJ
    201 nClgYp4Yh2JZ1Znbu7IoQMCEJCjwKDECIGd8Dzm5tViTkUW6Hs3Tlf73nNs65duF
    202 aRnSglss8I3pAiEAonEnKruawgD8RavDFR+fUgmQiPz4FnGGeVgfwpGG1JECIBYq
    203 PXHYtPqxQIbD2pScR5qum7iGUh11lEUPkmt+2uqS`,
    204 	},
    205 	{
    206 		// generated with:
    207 		// openssl genrsa -aes128 -passout pass:asdf -out server.orig.key 128
    208 		kind:     PEMCipherAES128,
    209 		password: []byte("asdf"),
    210 		pemData: []byte(`
    211 -----BEGIN RSA PRIVATE KEY-----
    212 Proc-Type: 4,ENCRYPTED
    213 DEK-Info: AES-128-CBC,74611ABC2571AF11B1BF9B69E62C89E7
    214 
    215 6ei/MlytjE0FFgZOGQ+jrwomKfpl8kdefeE0NSt/DMRrw8OacHAzBNi3pPEa0eX3
    216 eND9l7C9meCirWovjj9QWVHrXyugFuDIqgdhQ8iHTgCfF3lrmcttVrbIfMDw+smD
    217 hTP8O1mS/MHl92NE0nhv0w==
    218 -----END RSA PRIVATE KEY-----`),
    219 		plainDER: `
    220 MGMCAQACEQC6ssxmYuauuHGOCDAI54RdAgMBAAECEQCWIn6Yv2O+kBcDF7STctKB
    221 AgkA8SEfu/2i3g0CCQDGNlXbBHX7kQIIK3Ww5o0cYbECCQDCimPb0dYGsQIIeQ7A
    222 jryIst8=`,
    223 	},
    224 }
    225 
    226 const incompleteBlockPEM = `
    227 -----BEGIN RSA PRIVATE KEY-----
    228 Proc-Type: 4,ENCRYPTED
    229 DEK-Info: AES-128-CBC,74611ABC2571AF11B1BF9B69E62C89E7
    230 
    231 6L8yXK2MTQUWBk4ZD6OvCiYp+mXyR1594TQ1K38MxGvDw5pwcDME2Lek8RrR5fd40P2XsL2Z4KKt
    232 ai+OP1BZUetfK6AW4MiqB2FDyIdOAJ8XeWuZy21Wtsh8wPD6yYOFM/w7WZL8weX3Y0TSeG/T
    233 -----END RSA PRIVATE KEY-----`
    234 
    235 func TestIncompleteBlock(t *testing.T) {
    236 	// incompleteBlockPEM contains ciphertext that is not a multiple of the
    237 	// block size. This previously panicked. See #11215.
    238 	block, _ := pem.Decode([]byte(incompleteBlockPEM))
    239 	_, err := DecryptPEMBlock(block, []byte("foo"))
    240 	if err == nil {
    241 		t.Fatal("Bad PEM data decrypted successfully")
    242 	}
    243 	const expectedSubstr = "block size"
    244 	if e := err.Error(); !strings.Contains(e, expectedSubstr) {
    245 		t.Fatalf("Expected error containing %q but got: %q", expectedSubstr, e)
    246 	}
    247 }
    248