Home | History | Annotate | Download | only in pem
      1 // Copyright 2009 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 pem
      6 
      7 import (
      8 	"bytes"
      9 	"io/ioutil"
     10 	"reflect"
     11 	"strings"
     12 	"testing"
     13 	"testing/quick"
     14 )
     15 
     16 type GetLineTest struct {
     17 	in, out1, out2 string
     18 }
     19 
     20 var getLineTests = []GetLineTest{
     21 	{"abc", "abc", ""},
     22 	{"abc\r", "abc\r", ""},
     23 	{"abc\n", "abc", ""},
     24 	{"abc\r\n", "abc", ""},
     25 	{"abc\nd", "abc", "d"},
     26 	{"abc\r\nd", "abc", "d"},
     27 	{"\nabc", "", "abc"},
     28 	{"\r\nabc", "", "abc"},
     29 }
     30 
     31 func TestGetLine(t *testing.T) {
     32 	for i, test := range getLineTests {
     33 		x, y := getLine([]byte(test.in))
     34 		if string(x) != test.out1 || string(y) != test.out2 {
     35 			t.Errorf("#%d got:%+v,%+v want:%s,%s", i, x, y, test.out1, test.out2)
     36 		}
     37 	}
     38 }
     39 
     40 func TestDecode(t *testing.T) {
     41 	result, remainder := Decode([]byte(pemData))
     42 	if !reflect.DeepEqual(result, certificate) {
     43 		t.Errorf("#0 got:%#v want:%#v", result, certificate)
     44 	}
     45 	result, remainder = Decode(remainder)
     46 	if !reflect.DeepEqual(result, privateKey) {
     47 		t.Errorf("#1 got:%#v want:%#v", result, privateKey)
     48 	}
     49 
     50 	isEmpty := func(block *Block) bool {
     51 		return block != nil && block.Type == "EMPTY" && len(block.Headers) == 0 && len(block.Bytes) == 0
     52 	}
     53 	result, remainder = Decode(remainder)
     54 	if !isEmpty(result) {
     55 		t.Errorf("#2 should be empty but got:%#v", result)
     56 	}
     57 	result, remainder = Decode(remainder)
     58 	if !isEmpty(result) {
     59 		t.Errorf("#3 should be empty but got:%#v", result)
     60 	}
     61 	result, remainder = Decode(remainder)
     62 	if !isEmpty(result) {
     63 		t.Errorf("#4 should be empty but got:%#v", result)
     64 	}
     65 
     66 	result, remainder = Decode(remainder)
     67 	if result == nil || result.Type != "HEADERS" || len(result.Headers) != 1 {
     68 		t.Errorf("#5 expected single header block but got :%v", result)
     69 	}
     70 
     71 	if len(remainder) != 0 {
     72 		t.Errorf("expected nothing remaining of pemData, but found %s", string(remainder))
     73 	}
     74 
     75 	result, _ = Decode([]byte(pemPrivateKey2))
     76 	if !reflect.DeepEqual(result, privateKey2) {
     77 		t.Errorf("#2 got:%#v want:%#v", result, privateKey2)
     78 	}
     79 }
     80 
     81 const pemTooFewEndingDashes = `
     82 -----BEGIN FOO-----
     83 dGVzdA==
     84 -----END FOO----`
     85 
     86 const pemWrongEndingType = `
     87 -----BEGIN FOO-----
     88 dGVzdA==
     89 -----END BAR-----`
     90 
     91 const pemMissingEndingSpace = `
     92 -----BEGIN FOO-----
     93 dGVzdA==
     94 -----ENDBAR-----`
     95 
     96 var badPEMTests = []struct {
     97 	name  string
     98 	input string
     99 }{
    100 	{
    101 		"too few trailing dashes",
    102 		pemTooFewEndingDashes,
    103 	},
    104 	{
    105 		"incorrect ending type",
    106 		pemWrongEndingType,
    107 	},
    108 	{
    109 		"missing ending space",
    110 		pemMissingEndingSpace,
    111 	},
    112 }
    113 
    114 func TestBadDecode(t *testing.T) {
    115 	for _, test := range badPEMTests {
    116 		result, _ := Decode([]byte(test.input))
    117 		if result != nil {
    118 			t.Errorf("unexpected success while parsing %q", test.name)
    119 		}
    120 	}
    121 }
    122 
    123 func TestEncode(t *testing.T) {
    124 	r := EncodeToMemory(privateKey2)
    125 	if string(r) != pemPrivateKey2 {
    126 		t.Errorf("got:%s want:%s", r, pemPrivateKey2)
    127 	}
    128 }
    129 
    130 type lineBreakerTest struct {
    131 	in, out string
    132 }
    133 
    134 const sixtyFourCharString = "0123456789012345678901234567890123456789012345678901234567890123"
    135 
    136 var lineBreakerTests = []lineBreakerTest{
    137 	{"", ""},
    138 	{"a", "a\n"},
    139 	{"ab", "ab\n"},
    140 	{sixtyFourCharString, sixtyFourCharString + "\n"},
    141 	{sixtyFourCharString + "X", sixtyFourCharString + "\nX\n"},
    142 	{sixtyFourCharString + sixtyFourCharString, sixtyFourCharString + "\n" + sixtyFourCharString + "\n"},
    143 }
    144 
    145 func TestLineBreaker(t *testing.T) {
    146 	for i, test := range lineBreakerTests {
    147 		buf := new(bytes.Buffer)
    148 		var breaker lineBreaker
    149 		breaker.out = buf
    150 		_, err := breaker.Write([]byte(test.in))
    151 		if err != nil {
    152 			t.Errorf("#%d: error from Write: %s", i, err)
    153 			continue
    154 		}
    155 		err = breaker.Close()
    156 		if err != nil {
    157 			t.Errorf("#%d: error from Close: %s", i, err)
    158 			continue
    159 		}
    160 
    161 		if string(buf.Bytes()) != test.out {
    162 			t.Errorf("#%d: got:%s want:%s", i, string(buf.Bytes()), test.out)
    163 		}
    164 	}
    165 
    166 	for i, test := range lineBreakerTests {
    167 		buf := new(bytes.Buffer)
    168 		var breaker lineBreaker
    169 		breaker.out = buf
    170 
    171 		for i := 0; i < len(test.in); i++ {
    172 			_, err := breaker.Write([]byte(test.in[i : i+1]))
    173 			if err != nil {
    174 				t.Errorf("#%d: error from Write (byte by byte): %s", i, err)
    175 				continue
    176 			}
    177 		}
    178 		err := breaker.Close()
    179 		if err != nil {
    180 			t.Errorf("#%d: error from Close (byte by byte): %s", i, err)
    181 			continue
    182 		}
    183 
    184 		if string(buf.Bytes()) != test.out {
    185 			t.Errorf("#%d: (byte by byte) got:%s want:%s", i, string(buf.Bytes()), test.out)
    186 		}
    187 	}
    188 }
    189 
    190 func TestFuzz(t *testing.T) {
    191 	testRoundtrip := func(block Block) bool {
    192 		for key := range block.Headers {
    193 			if strings.Contains(key, ":") {
    194 				// Keys with colons cannot be encoded.
    195 				return true
    196 			}
    197 		}
    198 
    199 		var buf bytes.Buffer
    200 		if err := Encode(&buf, &block); err != nil {
    201 			t.Errorf("Encode of %#v resulted in error: %s", &block, err)
    202 			return false
    203 		}
    204 		decoded, rest := Decode(buf.Bytes())
    205 		if block.Headers == nil {
    206 			// Encoder supports nil Headers but decoder returns initialized.
    207 			block.Headers = make(map[string]string)
    208 		}
    209 		if block.Bytes == nil {
    210 			// Encoder supports nil Bytes but decoder returns initialized.
    211 			block.Bytes = make([]byte, 0)
    212 		}
    213 		if !reflect.DeepEqual(decoded, &block) {
    214 			t.Errorf("Encode of %#v decoded as %#v", &block, decoded)
    215 			return false
    216 		}
    217 		if len(rest) != 0 {
    218 			t.Errorf("Encode of %#v decoded correctly, but with %x left over", block, rest)
    219 			return false
    220 		}
    221 		return true
    222 	}
    223 
    224 	// Explicitly test the empty block.
    225 	if !testRoundtrip(Block{
    226 		Type:    "EMPTY",
    227 		Headers: make(map[string]string),
    228 		Bytes:   []byte{},
    229 	}) {
    230 		return
    231 	}
    232 
    233 	quick.Check(testRoundtrip, nil)
    234 }
    235 
    236 func BenchmarkEncode(b *testing.B) {
    237 	data := &Block{Bytes: make([]byte, 65536)}
    238 	b.SetBytes(int64(len(data.Bytes)))
    239 	for i := 0; i < b.N; i++ {
    240 		Encode(ioutil.Discard, data)
    241 	}
    242 }
    243 
    244 func BenchmarkDecode(b *testing.B) {
    245 	block := &Block{Bytes: make([]byte, 65536)}
    246 	data := EncodeToMemory(block)
    247 	b.SetBytes(int64(len(data)))
    248 	b.ResetTimer()
    249 	for i := 0; i < b.N; i++ {
    250 		Decode(data)
    251 	}
    252 }
    253 
    254 var pemData = `verify return:0
    255 -----BEGIN CERTIFICATE-----
    256 sdlfkjskldfj
    257   -----BEGIN CERTIFICATE-----
    258 ---
    259 Certificate chain
    260  0 s:/C=AU/ST=Somewhere/L=Someplace/O=Foo Bar/CN=foo.example.com
    261    i:/C=ZA/O=CA Inc./CN=CA Inc
    262 -----BEGIN CERTIFICATE-----
    263 testing
    264 -----BEGIN CERTIFICATE-----
    265 -----BEGIN CERTIFICATE----- 
    266 MIID6TCCA1ICAQEwDQYJKoZIhvcNAQEFBQAwgYsxCzAJBgNVBAYTAlVTMRMwEQYD
    267 VQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRQwEgYDVQQK
    268 EwtHb29nbGUgSW5jLjEMMAoGA1UECxMDRW5nMQwwCgYDVQQDEwNhZ2wxHTAbBgkq 
    269 hkiG9w0BCQEWDmFnbEBnb29nbGUuY29tMB4XDTA5MDkwOTIyMDU0M1oXDTEwMDkw  
    270 OTIyMDU0M1owajELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAf  	  
    271 BgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEjMCEGA1UEAxMaZXVyb3Bh		  
    272 LnNmby5jb3JwLmdvb2dsZS5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
    273 AoICAQC6pgYt7/EibBDumASF+S0qvqdL/f+nouJw2T1Qc8GmXF/iiUcrsgzh/Fd8
    274 pDhz/T96Qg9IyR4ztuc2MXrmPra+zAuSf5bevFReSqvpIt8Duv0HbDbcqs/XKPfB
    275 uMDe+of7a9GCywvAZ4ZUJcp0thqD9fKTTjUWOBzHY1uNE4RitrhmJCrbBGXbJ249
    276 bvgmb7jgdInH2PU7PT55hujvOoIsQW2osXBFRur4pF1wmVh4W4lTLD6pjfIMUcML
    277 ICHEXEN73PDic8KS3EtNYCwoIld+tpIBjE1QOb1KOyuJBNW6Esw9ALZn7stWdYcE
    278 qAwvv20egN2tEXqj7Q4/1ccyPZc3PQgC3FJ8Be2mtllM+80qf4dAaQ/fWvCtOrQ5
    279 pnfe9juQvCo8Y0VGlFcrSys/MzSg9LJ/24jZVgzQved/Qupsp89wVidwIzjt+WdS
    280 fyWfH0/v1aQLvu5cMYuW//C0W2nlYziL5blETntM8My2ybNARy3ICHxCBv2RNtPI
    281 WQVm+E9/W5rwh2IJR4DHn2LHwUVmT/hHNTdBLl5Uhwr4Wc7JhE7AVqb14pVNz1lr
    282 5jxsp//ncIwftb7mZQ3DF03Yna+jJhpzx8CQoeLT6aQCHyzmH68MrHHT4MALPyUs
    283 Pomjn71GNTtDeWAXibjCgdL6iHACCF6Htbl0zGlG0OAK+bdn0QIDAQABMA0GCSqG
    284 SIb3DQEBBQUAA4GBAOKnQDtqBV24vVqvesL5dnmyFpFPXBn3WdFfwD6DzEb21UVG
    285 5krmJiu+ViipORJPGMkgoL6BjU21XI95VQbun5P8vvg8Z+FnFsvRFY3e1CCzAVQY
    286 ZsUkLw2I7zI/dNlWdB8Xp7v+3w9sX5N3J/WuJ1KOO5m26kRlHQo7EzT3974g
    287 -----END CERTIFICATE-----   
    288  1 s:/C=ZA/O=Ca Inc./CN=CA Inc
    289 
    290 -----BEGIN RSA PRIVATE KEY-----   	
    291 Proc-Type: 4,ENCRYPTED	  
    292 DEK-Info: DES-EDE3-CBC,80C7C7A09690757A  	
    293   	
    294 eQp5ZkH6CyHBz7BZfUPxyLCCmftsBJ7HlqGb8Ld21cSwnzWZ4/SIlhyrUtsfw7VR
    295 2TTwA+odo9ex7GdxOTaH8oZFumIRoiEjHsk8U7Bhntp+ekkPP79xunnN7hb7hkhr   
    296 yGDQZgA7s2cQHQ71v3gwT2BACAft26jCjbM1wgNzBnJ8M0Rzn68YWqaPtdBu8qb/
    297 zVR5JB1mnqvTSbFsfF5yMc6o2WQ9jJCl6KypnMl+BpL+dlvdjYVK4l9lYsB1Hs3d
    298 +zDBbWxos818zzhS8/y6eIfiSG27cqrbhURbmgiSfDXjncK4m/pLcQ7mmBL6mFOr
    299 3Pj4jepzgOiFRL6MKE//h62fZvI1ErYr8VunHEykgKNhChDvb1RO6LEfqKBu+Ivw
    300 TB6fBhW3TCLMnVPYVoYwA+fHNTmZZm8BEonlIMfI+KktjWUg4Oia+NI6vKcPpFox
    301 hSnlGgCtvfEaq5/H4kHJp95eOpnFsLviw2seHNkz/LxJMRP1X428+DpYW/QD/0JU
    302 tJSuC/q9FUHL6RI3u/Asrv8pCb4+D7i1jW/AMIdJTtycOGsbPxQA7yHMWujHmeb1
    303 BTiHcL3s3KrJu1vDVrshvxfnz71KTeNnZH8UbOqT5i7fPGyXtY1XJddcbI/Q6tXf
    304 wHFsZc20TzSdsVLBtwksUacpbDogcEVMctnNrB8FIrB3vZEv9Q0Z1VeY7nmTpF+6
    305 a+z2P7acL7j6A6Pr3+q8P9CPiPC7zFonVzuVPyB8GchGR2hytyiOVpuD9+k8hcuw
    306 ZWAaUoVtWIQ52aKS0p19G99hhb+IVANC4akkdHV4SP8i7MVNZhfUmg==
    307 -----END RSA PRIVATE KEY-----
    308 
    309 
    310 -----BEGIN EMPTY-----
    311 -----END EMPTY-----
    312 
    313 -----BEGIN EMPTY-----
    314 
    315 -----END EMPTY-----
    316 
    317 -----BEGIN EMPTY-----
    318 
    319 
    320 -----END EMPTY-----
    321 
    322 # This shouldn't be recognised because of the missing newline after the
    323 headers.
    324 -----BEGIN HEADERS-----
    325 Header: 1
    326 -----END HEADERS-----
    327 
    328 # This should be valid, however.
    329 -----BEGIN HEADERS-----
    330 Header: 1
    331 
    332 -----END HEADERS-----`
    333 
    334 var certificate = &Block{Type: "CERTIFICATE",
    335 	Headers: map[string]string{},
    336 	Bytes: []uint8{0x30, 0x82, 0x3, 0xe9, 0x30, 0x82, 0x3, 0x52, 0x2, 0x1,
    337 		0x1, 0x30, 0xd, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd,
    338 		0x1, 0x1, 0x5, 0x5, 0x0, 0x30, 0x81, 0x8b, 0x31, 0xb, 0x30,
    339 		0x9, 0x6, 0x3, 0x55, 0x4, 0x6, 0x13, 0x2, 0x55, 0x53, 0x31,
    340 		0x13, 0x30, 0x11, 0x6, 0x3, 0x55, 0x4, 0x8, 0x13, 0xa, 0x43,
    341 		0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31,
    342 		0x16, 0x30, 0x14, 0x6, 0x3, 0x55, 0x4, 0x7, 0x13, 0xd, 0x53,
    343 		0x61, 0x6e, 0x20, 0x46, 0x72, 0x61, 0x6e, 0x63, 0x69, 0x73,
    344 		0x63, 0x6f, 0x31, 0x14, 0x30, 0x12, 0x6, 0x3, 0x55, 0x4, 0xa,
    345 		0x13, 0xb, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x20, 0x49,
    346 		0x6e, 0x63, 0x2e, 0x31, 0xc, 0x30, 0xa, 0x6, 0x3, 0x55, 0x4,
    347 		0xb, 0x13, 0x3, 0x45, 0x6e, 0x67, 0x31, 0xc, 0x30, 0xa, 0x6,
    348 		0x3, 0x55, 0x4, 0x3, 0x13, 0x3, 0x61, 0x67, 0x6c, 0x31, 0x1d,
    349 		0x30, 0x1b, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1,
    350 		0x9, 0x1, 0x16, 0xe, 0x61, 0x67, 0x6c, 0x40, 0x67, 0x6f, 0x6f,
    351 		0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17,
    352 		0xd, 0x30, 0x39, 0x30, 0x39, 0x30, 0x39, 0x32, 0x32, 0x30,
    353 		0x35, 0x34, 0x33, 0x5a, 0x17, 0xd, 0x31, 0x30, 0x30, 0x39,
    354 		0x30, 0x39, 0x32, 0x32, 0x30, 0x35, 0x34, 0x33, 0x5a, 0x30,
    355 		0x6a, 0x31, 0xb, 0x30, 0x9, 0x6, 0x3, 0x55, 0x4, 0x6, 0x13,
    356 		0x2, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x6, 0x3, 0x55, 0x4,
    357 		0x8, 0x13, 0xa, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61,
    358 		0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x6, 0x3, 0x55, 0x4, 0xa,
    359 		0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74,
    360 		0x20, 0x57, 0x69, 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50,
    361 		0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x31, 0x23, 0x30, 0x21,
    362 		0x6, 0x3, 0x55, 0x4, 0x3, 0x13, 0x1a, 0x65, 0x75, 0x72, 0x6f,
    363 		0x70, 0x61, 0x2e, 0x73, 0x66, 0x6f, 0x2e, 0x63, 0x6f, 0x72,
    364 		0x70, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63,
    365 		0x6f, 0x6d, 0x30, 0x82, 0x2, 0x22, 0x30, 0xd, 0x6, 0x9, 0x2a,
    366 		0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0x1, 0x5, 0x0, 0x3,
    367 		0x82, 0x2, 0xf, 0x0, 0x30, 0x82, 0x2, 0xa, 0x2, 0x82, 0x2, 0x1,
    368 		0x0, 0xba, 0xa6, 0x6, 0x2d, 0xef, 0xf1, 0x22, 0x6c, 0x10, 0xee,
    369 		0x98, 0x4, 0x85, 0xf9, 0x2d, 0x2a, 0xbe, 0xa7, 0x4b, 0xfd,
    370 		0xff, 0xa7, 0xa2, 0xe2, 0x70, 0xd9, 0x3d, 0x50, 0x73, 0xc1,
    371 		0xa6, 0x5c, 0x5f, 0xe2, 0x89, 0x47, 0x2b, 0xb2, 0xc, 0xe1,
    372 		0xfc, 0x57, 0x7c, 0xa4, 0x38, 0x73, 0xfd, 0x3f, 0x7a, 0x42,
    373 		0xf, 0x48, 0xc9, 0x1e, 0x33, 0xb6, 0xe7, 0x36, 0x31, 0x7a,
    374 		0xe6, 0x3e, 0xb6, 0xbe, 0xcc, 0xb, 0x92, 0x7f, 0x96, 0xde,
    375 		0xbc, 0x54, 0x5e, 0x4a, 0xab, 0xe9, 0x22, 0xdf, 0x3, 0xba,
    376 		0xfd, 0x7, 0x6c, 0x36, 0xdc, 0xaa, 0xcf, 0xd7, 0x28, 0xf7,
    377 		0xc1, 0xb8, 0xc0, 0xde, 0xfa, 0x87, 0xfb, 0x6b, 0xd1, 0x82,
    378 		0xcb, 0xb, 0xc0, 0x67, 0x86, 0x54, 0x25, 0xca, 0x74, 0xb6,
    379 		0x1a, 0x83, 0xf5, 0xf2, 0x93, 0x4e, 0x35, 0x16, 0x38, 0x1c,
    380 		0xc7, 0x63, 0x5b, 0x8d, 0x13, 0x84, 0x62, 0xb6, 0xb8, 0x66,
    381 		0x24, 0x2a, 0xdb, 0x4, 0x65, 0xdb, 0x27, 0x6e, 0x3d, 0x6e,
    382 		0xf8, 0x26, 0x6f, 0xb8, 0xe0, 0x74, 0x89, 0xc7, 0xd8, 0xf5,
    383 		0x3b, 0x3d, 0x3e, 0x79, 0x86, 0xe8, 0xef, 0x3a, 0x82, 0x2c,
    384 		0x41, 0x6d, 0xa8, 0xb1, 0x70, 0x45, 0x46, 0xea, 0xf8, 0xa4,
    385 		0x5d, 0x70, 0x99, 0x58, 0x78, 0x5b, 0x89, 0x53, 0x2c, 0x3e,
    386 		0xa9, 0x8d, 0xf2, 0xc, 0x51, 0xc3, 0xb, 0x20, 0x21, 0xc4, 0x5c,
    387 		0x43, 0x7b, 0xdc, 0xf0, 0xe2, 0x73, 0xc2, 0x92, 0xdc, 0x4b,
    388 		0x4d, 0x60, 0x2c, 0x28, 0x22, 0x57, 0x7e, 0xb6, 0x92, 0x1,
    389 		0x8c, 0x4d, 0x50, 0x39, 0xbd, 0x4a, 0x3b, 0x2b, 0x89, 0x4,
    390 		0xd5, 0xba, 0x12, 0xcc, 0x3d, 0x0, 0xb6, 0x67, 0xee, 0xcb,
    391 		0x56, 0x75, 0x87, 0x4, 0xa8, 0xc, 0x2f, 0xbf, 0x6d, 0x1e, 0x80,
    392 		0xdd, 0xad, 0x11, 0x7a, 0xa3, 0xed, 0xe, 0x3f, 0xd5, 0xc7,
    393 		0x32, 0x3d, 0x97, 0x37, 0x3d, 0x8, 0x2, 0xdc, 0x52, 0x7c, 0x5,
    394 		0xed, 0xa6, 0xb6, 0x59, 0x4c, 0xfb, 0xcd, 0x2a, 0x7f, 0x87,
    395 		0x40, 0x69, 0xf, 0xdf, 0x5a, 0xf0, 0xad, 0x3a, 0xb4, 0x39,
    396 		0xa6, 0x77, 0xde, 0xf6, 0x3b, 0x90, 0xbc, 0x2a, 0x3c, 0x63,
    397 		0x45, 0x46, 0x94, 0x57, 0x2b, 0x4b, 0x2b, 0x3f, 0x33, 0x34,
    398 		0xa0, 0xf4, 0xb2, 0x7f, 0xdb, 0x88, 0xd9, 0x56, 0xc, 0xd0,
    399 		0xbd, 0xe7, 0x7f, 0x42, 0xea, 0x6c, 0xa7, 0xcf, 0x70, 0x56,
    400 		0x27, 0x70, 0x23, 0x38, 0xed, 0xf9, 0x67, 0x52, 0x7f, 0x25,
    401 		0x9f, 0x1f, 0x4f, 0xef, 0xd5, 0xa4, 0xb, 0xbe, 0xee, 0x5c,
    402 		0x31, 0x8b, 0x96, 0xff, 0xf0, 0xb4, 0x5b, 0x69, 0xe5, 0x63,
    403 		0x38, 0x8b, 0xe5, 0xb9, 0x44, 0x4e, 0x7b, 0x4c, 0xf0, 0xcc,
    404 		0xb6, 0xc9, 0xb3, 0x40, 0x47, 0x2d, 0xc8, 0x8, 0x7c, 0x42, 0x6,
    405 		0xfd, 0x91, 0x36, 0xd3, 0xc8, 0x59, 0x5, 0x66, 0xf8, 0x4f,
    406 		0x7f, 0x5b, 0x9a, 0xf0, 0x87, 0x62, 0x9, 0x47, 0x80, 0xc7,
    407 		0x9f, 0x62, 0xc7, 0xc1, 0x45, 0x66, 0x4f, 0xf8, 0x47, 0x35,
    408 		0x37, 0x41, 0x2e, 0x5e, 0x54, 0x87, 0xa, 0xf8, 0x59, 0xce,
    409 		0xc9, 0x84, 0x4e, 0xc0, 0x56, 0xa6, 0xf5, 0xe2, 0x95, 0x4d,
    410 		0xcf, 0x59, 0x6b, 0xe6, 0x3c, 0x6c, 0xa7, 0xff, 0xe7, 0x70,
    411 		0x8c, 0x1f, 0xb5, 0xbe, 0xe6, 0x65, 0xd, 0xc3, 0x17, 0x4d,
    412 		0xd8, 0x9d, 0xaf, 0xa3, 0x26, 0x1a, 0x73, 0xc7, 0xc0, 0x90,
    413 		0xa1, 0xe2, 0xd3, 0xe9, 0xa4, 0x2, 0x1f, 0x2c, 0xe6, 0x1f,
    414 		0xaf, 0xc, 0xac, 0x71, 0xd3, 0xe0, 0xc0, 0xb, 0x3f, 0x25, 0x2c,
    415 		0x3e, 0x89, 0xa3, 0x9f, 0xbd, 0x46, 0x35, 0x3b, 0x43, 0x79,
    416 		0x60, 0x17, 0x89, 0xb8, 0xc2, 0x81, 0xd2, 0xfa, 0x88, 0x70,
    417 		0x2, 0x8, 0x5e, 0x87, 0xb5, 0xb9, 0x74, 0xcc, 0x69, 0x46, 0xd0,
    418 		0xe0, 0xa, 0xf9, 0xb7, 0x67, 0xd1, 0x2, 0x3, 0x1, 0x0, 0x1,
    419 		0x30, 0xd, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1,
    420 		0x1, 0x5, 0x5, 0x0, 0x3, 0x81, 0x81, 0x0, 0xe2, 0xa7, 0x40,
    421 		0x3b, 0x6a, 0x5, 0x5d, 0xb8, 0xbd, 0x5a, 0xaf, 0x7a, 0xc2,
    422 		0xf9, 0x76, 0x79, 0xb2, 0x16, 0x91, 0x4f, 0x5c, 0x19, 0xf7,
    423 		0x59, 0xd1, 0x5f, 0xc0, 0x3e, 0x83, 0xcc, 0x46, 0xf6, 0xd5,
    424 		0x45, 0x46, 0xe6, 0x4a, 0xe6, 0x26, 0x2b, 0xbe, 0x56, 0x28,
    425 		0xa9, 0x39, 0x12, 0x4f, 0x18, 0xc9, 0x20, 0xa0, 0xbe, 0x81,
    426 		0x8d, 0x4d, 0xb5, 0x5c, 0x8f, 0x79, 0x55, 0x6, 0xee, 0x9f,
    427 		0x93, 0xfc, 0xbe, 0xf8, 0x3c, 0x67, 0xe1, 0x67, 0x16, 0xcb,
    428 		0xd1, 0x15, 0x8d, 0xde, 0xd4, 0x20, 0xb3, 0x1, 0x54, 0x18,
    429 		0x66, 0xc5, 0x24, 0x2f, 0xd, 0x88, 0xef, 0x32, 0x3f, 0x74,
    430 		0xd9, 0x56, 0x74, 0x1f, 0x17, 0xa7, 0xbb, 0xfe, 0xdf, 0xf,
    431 		0x6c, 0x5f, 0x93, 0x77, 0x27, 0xf5, 0xae, 0x27, 0x52, 0x8e,
    432 		0x3b, 0x99, 0xb6, 0xea, 0x44, 0x65, 0x1d, 0xa, 0x3b, 0x13,
    433 		0x34, 0xf7, 0xf7, 0xbe, 0x20,
    434 	},
    435 }
    436 
    437 var privateKey = &Block{Type: "RSA PRIVATE KEY",
    438 	Headers: map[string]string{"DEK-Info": "DES-EDE3-CBC,80C7C7A09690757A", "Proc-Type": "4,ENCRYPTED"},
    439 	Bytes: []uint8{0x79, 0xa, 0x79, 0x66, 0x41, 0xfa, 0xb,
    440 		0x21, 0xc1, 0xcf, 0xb0, 0x59, 0x7d, 0x43, 0xf1, 0xc8, 0xb0,
    441 		0x82, 0x99, 0xfb, 0x6c, 0x4, 0x9e, 0xc7, 0x96, 0xa1, 0x9b,
    442 		0xf0, 0xb7, 0x76, 0xd5, 0xc4, 0xb0, 0x9f, 0x35, 0x99, 0xe3,
    443 		0xf4, 0x88, 0x96, 0x1c, 0xab, 0x52, 0xdb, 0x1f, 0xc3, 0xb5,
    444 		0x51, 0xd9, 0x34, 0xf0, 0x3, 0xea, 0x1d, 0xa3, 0xd7, 0xb1,
    445 		0xec, 0x67, 0x71, 0x39, 0x36, 0x87, 0xf2, 0x86, 0x45, 0xba,
    446 		0x62, 0x11, 0xa2, 0x21, 0x23, 0x1e, 0xc9, 0x3c, 0x53, 0xb0,
    447 		0x61, 0x9e, 0xda, 0x7e, 0x7a, 0x49, 0xf, 0x3f, 0xbf, 0x71,
    448 		0xba, 0x79, 0xcd, 0xee, 0x16, 0xfb, 0x86, 0x48, 0x6b, 0xc8,
    449 		0x60, 0xd0, 0x66, 0x0, 0x3b, 0xb3, 0x67, 0x10, 0x1d, 0xe,
    450 		0xf5, 0xbf, 0x78, 0x30, 0x4f, 0x60, 0x40, 0x8, 0x7, 0xed,
    451 		0xdb, 0xa8, 0xc2, 0x8d, 0xb3, 0x35, 0xc2, 0x3, 0x73, 0x6,
    452 		0x72, 0x7c, 0x33, 0x44, 0x73, 0x9f, 0xaf, 0x18, 0x5a, 0xa6,
    453 		0x8f, 0xb5, 0xd0, 0x6e, 0xf2, 0xa6, 0xff, 0xcd, 0x54, 0x79,
    454 		0x24, 0x1d, 0x66, 0x9e, 0xab, 0xd3, 0x49, 0xb1, 0x6c, 0x7c,
    455 		0x5e, 0x72, 0x31, 0xce, 0xa8, 0xd9, 0x64, 0x3d, 0x8c, 0x90,
    456 		0xa5, 0xe8, 0xac, 0xa9, 0x9c, 0xc9, 0x7e, 0x6, 0x92, 0xfe,
    457 		0x76, 0x5b, 0xdd, 0x8d, 0x85, 0x4a, 0xe2, 0x5f, 0x65, 0x62,
    458 		0xc0, 0x75, 0x1e, 0xcd, 0xdd, 0xfb, 0x30, 0xc1, 0x6d, 0x6c,
    459 		0x68, 0xb3, 0xcd, 0x7c, 0xcf, 0x38, 0x52, 0xf3, 0xfc, 0xba,
    460 		0x78, 0x87, 0xe2, 0x48, 0x6d, 0xbb, 0x72, 0xaa, 0xdb, 0x85,
    461 		0x44, 0x5b, 0x9a, 0x8, 0x92, 0x7c, 0x35, 0xe3, 0x9d, 0xc2,
    462 		0xb8, 0x9b, 0xfa, 0x4b, 0x71, 0xe, 0xe6, 0x98, 0x12, 0xfa,
    463 		0x98, 0x53, 0xab, 0xdc, 0xf8, 0xf8, 0x8d, 0xea, 0x73, 0x80,
    464 		0xe8, 0x85, 0x44, 0xbe, 0x8c, 0x28, 0x4f, 0xff, 0x87, 0xad,
    465 		0x9f, 0x66, 0xf2, 0x35, 0x12, 0xb6, 0x2b, 0xf1, 0x5b, 0xa7,
    466 		0x1c, 0x4c, 0xa4, 0x80, 0xa3, 0x61, 0xa, 0x10, 0xef, 0x6f,
    467 		0x54, 0x4e, 0xe8, 0xb1, 0x1f, 0xa8, 0xa0, 0x6e, 0xf8, 0x8b,
    468 		0xf0, 0x4c, 0x1e, 0x9f, 0x6, 0x15, 0xb7, 0x4c, 0x22, 0xcc,
    469 		0x9d, 0x53, 0xd8, 0x56, 0x86, 0x30, 0x3, 0xe7, 0xc7, 0x35,
    470 		0x39, 0x99, 0x66, 0x6f, 0x1, 0x12, 0x89, 0xe5, 0x20, 0xc7,
    471 		0xc8, 0xf8, 0xa9, 0x2d, 0x8d, 0x65, 0x20, 0xe0, 0xe8, 0x9a,
    472 		0xf8, 0xd2, 0x3a, 0xbc, 0xa7, 0xf, 0xa4, 0x5a, 0x31, 0x85,
    473 		0x29, 0xe5, 0x1a, 0x0, 0xad, 0xbd, 0xf1, 0x1a, 0xab, 0x9f,
    474 		0xc7, 0xe2, 0x41, 0xc9, 0xa7, 0xde, 0x5e, 0x3a, 0x99, 0xc5,
    475 		0xb0, 0xbb, 0xe2, 0xc3, 0x6b, 0x1e, 0x1c, 0xd9, 0x33, 0xfc,
    476 		0xbc, 0x49, 0x31, 0x13, 0xf5, 0x5f, 0x8d, 0xbc, 0xf8, 0x3a,
    477 		0x58, 0x5b, 0xf4, 0x3, 0xff, 0x42, 0x54, 0xb4, 0x94, 0xae,
    478 		0xb, 0xfa, 0xbd, 0x15, 0x41, 0xcb, 0xe9, 0x12, 0x37, 0xbb,
    479 		0xf0, 0x2c, 0xae, 0xff, 0x29, 0x9, 0xbe, 0x3e, 0xf, 0xb8,
    480 		0xb5, 0x8d, 0x6f, 0xc0, 0x30, 0x87, 0x49, 0x4e, 0xdc, 0x9c,
    481 		0x38, 0x6b, 0x1b, 0x3f, 0x14, 0x0, 0xef, 0x21, 0xcc, 0x5a,
    482 		0xe8, 0xc7, 0x99, 0xe6, 0xf5, 0x5, 0x38, 0x87, 0x70, 0xbd,
    483 		0xec, 0xdc, 0xaa, 0xc9, 0xbb, 0x5b, 0xc3, 0x56, 0xbb, 0x21,
    484 		0xbf, 0x17, 0xe7, 0xcf, 0xbd, 0x4a, 0x4d, 0xe3, 0x67, 0x64,
    485 		0x7f, 0x14, 0x6c, 0xea, 0x93, 0xe6, 0x2e, 0xdf, 0x3c, 0x6c,
    486 		0x97, 0xb5, 0x8d, 0x57, 0x25, 0xd7, 0x5c, 0x6c, 0x8f, 0xd0,
    487 		0xea, 0xd5, 0xdf, 0xc0, 0x71, 0x6c, 0x65, 0xcd, 0xb4, 0x4f,
    488 		0x34, 0x9d, 0xb1, 0x52, 0xc1, 0xb7, 0x9, 0x2c, 0x51, 0xa7,
    489 		0x29, 0x6c, 0x3a, 0x20, 0x70, 0x45, 0x4c, 0x72, 0xd9, 0xcd,
    490 		0xac, 0x1f, 0x5, 0x22, 0xb0, 0x77, 0xbd, 0x91, 0x2f, 0xf5,
    491 		0xd, 0x19, 0xd5, 0x57, 0x98, 0xee, 0x79, 0x93, 0xa4, 0x5f,
    492 		0xba, 0x6b, 0xec, 0xf6, 0x3f, 0xb6, 0x9c, 0x2f, 0xb8, 0xfa,
    493 		0x3, 0xa3, 0xeb, 0xdf, 0xea, 0xbc, 0x3f, 0xd0, 0x8f, 0x88,
    494 		0xf0, 0xbb, 0xcc, 0x5a, 0x27, 0x57, 0x3b, 0x95, 0x3f, 0x20,
    495 		0x7c, 0x19, 0xc8, 0x46, 0x47, 0x68, 0x72, 0xb7, 0x28, 0x8e,
    496 		0x56, 0x9b, 0x83, 0xf7, 0xe9, 0x3c, 0x85, 0xcb, 0xb0, 0x65,
    497 		0x60, 0x1a, 0x52, 0x85, 0x6d, 0x58, 0x84, 0x39, 0xd9, 0xa2,
    498 		0x92, 0xd2, 0x9d, 0x7d, 0x1b, 0xdf, 0x61, 0x85, 0xbf, 0x88,
    499 		0x54, 0x3, 0x42, 0xe1, 0xa9, 0x24, 0x74, 0x75, 0x78, 0x48,
    500 		0xff, 0x22, 0xec, 0xc5, 0x4d, 0x66, 0x17, 0xd4, 0x9a,
    501 	},
    502 }
    503 
    504 var privateKey2 = &Block{
    505 	Type: "RSA PRIVATE KEY",
    506 	Headers: map[string]string{
    507 		"Proc-Type":      "4,ENCRYPTED",
    508 		"DEK-Info":       "AES-128-CBC,BFCD243FEDBB40A4AA6DDAA1335473A4",
    509 		"Content-Domain": "RFC822",
    510 	},
    511 	Bytes: []uint8{
    512 		0xa8, 0x35, 0xcc, 0x2b, 0xb9, 0xcb, 0x21, 0xab, 0xc0,
    513 		0x9d, 0x76, 0x61, 0x0, 0xf4, 0x81, 0xad, 0x69, 0xd2,
    514 		0xc0, 0x42, 0x41, 0x3b, 0xe4, 0x3c, 0xaf, 0x59, 0x5e,
    515 		0x6d, 0x2a, 0x3c, 0x9c, 0xa1, 0xa4, 0x5e, 0x68, 0x37,
    516 		0xc4, 0x8c, 0x70, 0x1c, 0xa9, 0x18, 0xe6, 0xc2, 0x2b,
    517 		0x8a, 0x91, 0xdc, 0x2d, 0x1f, 0x8, 0x23, 0x39, 0xf1,
    518 		0x4b, 0x8b, 0x1b, 0x2f, 0x46, 0xb, 0xb2, 0x26, 0xba,
    519 		0x4f, 0x40, 0x80, 0x39, 0xc4, 0xb1, 0xcb, 0x3b, 0xb4,
    520 		0x65, 0x3f, 0x1b, 0xb2, 0xf7, 0x8, 0xd2, 0xc6, 0xd5,
    521 		0xa8, 0x9f, 0x23, 0x69, 0xb6, 0x3d, 0xf9, 0xac, 0x1c,
    522 		0xb3, 0x13, 0x87, 0x64, 0x4, 0x37, 0xdb, 0x40, 0xc8,
    523 		0x82, 0xc, 0xd0, 0xf8, 0x21, 0x7c, 0xdc, 0xbd, 0x9, 0x4,
    524 		0x20, 0x16, 0xb0, 0x97, 0xe2, 0x6d, 0x56, 0x1d, 0xe3,
    525 		0xec, 0xf0, 0xfc, 0xe2, 0x56, 0xad, 0xa4, 0x3, 0x70,
    526 		0x6d, 0x63, 0x3c, 0x1, 0xbe, 0x3e, 0x28, 0x38, 0x6f,
    527 		0xc0, 0xe6, 0xfd, 0x85, 0xd1, 0x53, 0xa8, 0x9b, 0xcb,
    528 		0xd4, 0x4, 0xb1, 0x73, 0xb9, 0x73, 0x32, 0xd6, 0x7a,
    529 		0xc6, 0x29, 0x25, 0xa5, 0xda, 0x17, 0x93, 0x7a, 0x10,
    530 		0xe8, 0x41, 0xfb, 0xa5, 0x17, 0x20, 0xf8, 0x4e, 0xe9,
    531 		0xe3, 0x8f, 0x51, 0x20, 0x13, 0xbb, 0xde, 0xb7, 0x93,
    532 		0xae, 0x13, 0x8a, 0xf6, 0x9, 0xf4, 0xa6, 0x41, 0xe0,
    533 		0x2b, 0x51, 0x1a, 0x30, 0x38, 0xd, 0xb1, 0x3b, 0x67,
    534 		0x87, 0x64, 0xf5, 0xca, 0x32, 0x67, 0xd1, 0xc8, 0xa5,
    535 		0x3d, 0x23, 0x72, 0xc4, 0x6, 0xaf, 0x8f, 0x7b, 0x26,
    536 		0xac, 0x3c, 0x75, 0x91, 0xa1, 0x0, 0x13, 0xc6, 0x5c,
    537 		0x49, 0xd5, 0x3c, 0xe7, 0xb2, 0xb2, 0x99, 0xe0, 0xd5,
    538 		0x25, 0xfa, 0xe2, 0x12, 0x80, 0x37, 0x85, 0xcf, 0x92,
    539 		0xca, 0x1b, 0x9f, 0xf3, 0x4e, 0xd8, 0x80, 0xef, 0x3c,
    540 		0xce, 0xcd, 0xf5, 0x90, 0x9e, 0xf9, 0xa7, 0xb2, 0xc,
    541 		0x49, 0x4, 0xf1, 0x9, 0x8f, 0xea, 0x63, 0xd2, 0x70,
    542 		0xbb, 0x86, 0xbf, 0x34, 0xab, 0xb2, 0x3, 0xb1, 0x59,
    543 		0x33, 0x16, 0x17, 0xb0, 0xdb, 0x77, 0x38, 0xf4, 0xb4,
    544 		0x94, 0xb, 0x25, 0x16, 0x7e, 0x22, 0xd4, 0xf9, 0x22,
    545 		0xb9, 0x78, 0xa3, 0x4, 0x84, 0x4, 0xd2, 0xda, 0x84,
    546 		0x2d, 0x63, 0xdd, 0xf8, 0x50, 0x6a, 0xf6, 0xe3, 0xf5,
    547 		0x65, 0x40, 0x7c, 0xa9,
    548 	},
    549 }
    550 
    551 var pemPrivateKey2 = `-----BEGIN RSA PRIVATE KEY-----
    552 Proc-Type: 4,ENCRYPTED
    553 Content-Domain: RFC822
    554 DEK-Info: AES-128-CBC,BFCD243FEDBB40A4AA6DDAA1335473A4
    555 
    556 qDXMK7nLIavAnXZhAPSBrWnSwEJBO+Q8r1lebSo8nKGkXmg3xIxwHKkY5sIripHc
    557 LR8IIznxS4sbL0YLsia6T0CAOcSxyzu0ZT8bsvcI0sbVqJ8jabY9+awcsxOHZAQ3
    558 20DIggzQ+CF83L0JBCAWsJfibVYd4+zw/OJWraQDcG1jPAG+Pig4b8Dm/YXRU6ib
    559 y9QEsXO5czLWesYpJaXaF5N6EOhB+6UXIPhO6eOPUSATu963k64TivYJ9KZB4CtR
    560 GjA4DbE7Z4dk9coyZ9HIpT0jcsQGr497Jqw8dZGhABPGXEnVPOeyspng1SX64hKA
    561 N4XPksobn/NO2IDvPM7N9ZCe+aeyDEkE8QmP6mPScLuGvzSrsgOxWTMWF7Dbdzj0
    562 tJQLJRZ+ItT5Irl4owSEBNLahC1j3fhQavbj9WVAfKk=
    563 -----END RSA PRIVATE KEY-----
    564 `
    565