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