package acmeutils

import (
	"bytes"
	"crypto/ecdsa"
	"crypto/elliptic"
	"crypto/rsa"
	"math/big"
	"reflect"
	"testing"
)

const testCerts = `-----BEGIN CERTIFICATE-----
MIIEmzCCA4OgAwIBAgITAP8qTldZTvtEDieNbQA7/6O6mDANBgkqhkiG9w0BAQsF
ADAfMR0wGwYDVQQDExRoYXBweSBoYWNrZXIgZmFrZSBDQTAeFw0xNTExMjcxMTE1
MDBaFw0xNjAyMjUxMTE1MDBaMCkxJzAlBgNVBAMTHmRvbTEuYWNtZXRvb2wtdGVz
dC5kZXZldmVyLm5ldDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMKQ
an2mcZAIWqu7J5/6n+KQ521+VlsJEe3189hLJfzTbxpDxag/DiJo2xcl4jZeEAkr
FR4JZxs693lh92YnbSfWwZ0IvjEUNOYJGs9L59wADTu7wEoM2xAWWSUh85ziKwpb
P/JE7i1D4+Mlll/xEcfbzpbYdlGKND76wAGyapJ4ozdXr2Bjtp4rEiMGjyOfgbur
ex20Fyv1A40UwdaKdypnmtEyXIdP++/dj4yWGX3rszyO1erGzsCIng9EDhPreL3c
7uZVnZJrrlUPS7mPJzPfjUZhCWK9BQniAoSHiZiB0lAB2TUNU4gaqGgj4TDv1KPa
pqP1spdcIWGqA+40j70CAwEAAaOCAcQwggHAMA4GA1UdDwEB/wQEAwIFoDAdBgNV
HSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAdBgNVHQ4E
FgQUO1JtuzcEAU6kv0VQlEcL59SvNOQwHwYDVR0jBBgwFoAU+3hPEvlgFYMsnxd/
NBmzLjbqQYkwagYIKwYBBQUHAQEEXjBcMCYGCCsGAQUFBzABhhpodHRwOi8vMTI3
LjAuMC4xOjQwMDIvb2NzcDAyBggrBgEFBQcwAoYmaHR0cDovLzEyNy4wLjAuMTo0
MDAwL2FjbWUvaXNzdWVyLWNlcnQwSQYDVR0RBEIwQIIeZG9tMS5hY21ldG9vbC10
ZXN0LmRldmV2ZXIubmV0gh5kb20yLmFjbWV0b29sLXRlc3QuZGV2ZXZlci5uZXQw
JwYDVR0fBCAwHjAcoBqgGIYWaHR0cDovL2V4YW1wbGUuY29tL2NybDBhBgNVHSAE
WjBYMAgGBmeBDAECATBMBgMqAwQwRTAiBggrBgEFBQcCARYWaHR0cDovL2V4YW1w
bGUuY29tL2NwczAfBggrBgEFBQcCAjATDBFEbyBXaGF0IFRob3UgV2lsdDANBgkq
hkiG9w0BAQsFAAOCAQEAhpchBW1k++LrbyaCG0Y8dpJY01TDhKxNoMrEGTd7UH0F
7Ar+kBPOcf0gglvX6gcZzcJkILQTbBct5Lvqta+j/JMkseAoAFr31GWP7SdeOsmi
txzWmbL+Mm256jqXPYewUiK1k9HpmPT9CajS6T/f2Q0RvRQgRD4e2B61kTRMt3t4
p7u0/wF5PDzsj8oC0D/yUSBU7icWHPkzuKhw+zjYZPoVdyEe0CoLMtTskPZooZby
M+ngFyg3Boy1R4px/mmdV1fds5nHdZ+R6g2qe7FT7LB8KUVsUMEyCUiDIzeu1WLn
vWa/xVfwBbKvgMjnHs31qODbsSzRRpNgX0NWE14jew==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEijCCA3KgAwIBAgICEk0wDQYJKoZIhvcNAQELBQAwKzEpMCcGA1UEAwwgY2Fj
a2xpbmcgY3J5cHRvZ3JhcGhlciBmYWtlIFJPT1QwHhcNMTUxMDIxMjAxMTUyWhcN
MjAxMDE5MjAxMTUyWjAfMR0wGwYDVQQDExRoYXBweSBoYWNrZXIgZmFrZSBDQTCC
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMIKR3maBcUSsncXYzQT13D5
Nr+Z3mLxMMh3TUdt6sACmqbJ0btRlgXfMtNLM2OU1I6a3Ju+tIZSdn2v21JBwvxU
zpZQ4zy2cimIiMQDZCQHJwzC9GZn8HaW091iz9H0Go3A7WDXwYNmsdLNRi00o14U
joaVqaPsYrZWvRKaIRqaU0hHmS0AWwQSvN/93iMIXuyiwywmkwKbWnnxCQ/gsctK
FUtcNrwEx9Wgj6KlhwDTyI1QWSBbxVYNyUgPFzKxrSmwMO0yNff7ho+QT9x5+Y/7
XE59S4Mc4ZXxcXKew/gSlN9U5mvT+D2BhDtkCupdfsZNCQWp27A+b/DmrFI9NqsC
AwEAAaOCAcIwggG+MBIGA1UdEwEB/wQIMAYBAf8CAQAwQwYDVR0eBDwwOqE4MAaC
BC5taWwwCocIAAAAAAAAAAAwIocgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAwDgYDVR0PAQH/BAQDAgGGMH8GCCsGAQUFBwEBBHMwcTAyBggrBgEFBQcw
AYYmaHR0cDovL2lzcmcudHJ1c3RpZC5vY3NwLmlkZW50cnVzdC5jb20wOwYIKwYB
BQUHMAKGL2h0dHA6Ly9hcHBzLmlkZW50cnVzdC5jb20vcm9vdHMvZHN0cm9vdGNh
eDMucDdjMB8GA1UdIwQYMBaAFOmkP+6epeby1dd5YDyTpi4kjpeqMFQGA1UdIARN
MEswCAYGZ4EMAQIBMD8GCysGAQQBgt8TAQEBMDAwLgYIKwYBBQUHAgEWImh0dHA6
Ly9jcHMucm9vdC14MS5sZXRzZW5jcnlwdC5vcmcwPAYDVR0fBDUwMzAxoC+gLYYr
aHR0cDovL2NybC5pZGVudHJ1c3QuY29tL0RTVFJPT1RDQVgzQ1JMLmNybDAdBgNV
HQ4EFgQU+3hPEvlgFYMsnxd/NBmzLjbqQYkwDQYJKoZIhvcNAQELBQADggEBAA0Y
AeLXOklx4hhCikUUl+BdnFfn1g0W5AiQLVNIOL6PnqXu0wjnhNyhqdwnfhYMnoy4
idRh4lB6pz8Gf9pnlLd/DnWSV3gS+/I/mAl1dCkKby6H2V790e6IHmIK2KYm3jm+
U++FIdGpBdsQTSdmiX/rAyuxMDM0adMkNBwTfQmZQCz6nGHw1QcSPZMvZpsC8Skv
ekzxsjF1otOrMUPNPQvtTWrVx8GlR2qfx/4xbQa1v2frNvFBCmO59goz+jnWvfTt
j2NjwDZ7vlMBsPm16dbKYC840uvRoZjxqsdc3ChCZjqimFqlNG/xoPA8+dTicZzC
XE9ijPIcvW6y1aa3bGw=
-----END CERTIFICATE-----`

var testCertsDER = [][]byte{
	{
		0x30, 0x82, 0x04, 0x9b, 0x30, 0x82, 0x03, 0x83, 0xa0, 0x03, 0x02, 0x01,
		0x02, 0x02, 0x13, 0x00, 0xff, 0x2a, 0x4e, 0x57, 0x59, 0x4e, 0xfb, 0x44,
		0x0e, 0x27, 0x8d, 0x6d, 0x00, 0x3b, 0xff, 0xa3, 0xba, 0x98, 0x30, 0x0d,
		0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05,
		0x00, 0x30, 0x1f, 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03,
		0x13, 0x14, 0x68, 0x61, 0x70, 0x70, 0x79, 0x20, 0x68, 0x61, 0x63, 0x6b,
		0x65, 0x72, 0x20, 0x66, 0x61, 0x6b, 0x65, 0x20, 0x43, 0x41, 0x30, 0x1e,
		0x17, 0x0d, 0x31, 0x35, 0x31, 0x31, 0x32, 0x37, 0x31, 0x31, 0x31, 0x35,
		0x30, 0x30, 0x5a, 0x17, 0x0d, 0x31, 0x36, 0x30, 0x32, 0x32, 0x35, 0x31,
		0x31, 0x31, 0x35, 0x30, 0x30, 0x5a, 0x30, 0x29, 0x31, 0x27, 0x30, 0x25,
		0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1e, 0x64, 0x6f, 0x6d, 0x31, 0x2e,
		0x61, 0x63, 0x6d, 0x65, 0x74, 0x6f, 0x6f, 0x6c, 0x2d, 0x74, 0x65, 0x73,
		0x74, 0x2e, 0x64, 0x65, 0x76, 0x65, 0x76, 0x65, 0x72, 0x2e, 0x6e, 0x65,
		0x74, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
		0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f,
		0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xc2, 0x90,
		0x6a, 0x7d, 0xa6, 0x71, 0x90, 0x08, 0x5a, 0xab, 0xbb, 0x27, 0x9f, 0xfa,
		0x9f, 0xe2, 0x90, 0xe7, 0x6d, 0x7e, 0x56, 0x5b, 0x09, 0x11, 0xed, 0xf5,
		0xf3, 0xd8, 0x4b, 0x25, 0xfc, 0xd3, 0x6f, 0x1a, 0x43, 0xc5, 0xa8, 0x3f,
		0x0e, 0x22, 0x68, 0xdb, 0x17, 0x25, 0xe2, 0x36, 0x5e, 0x10, 0x09, 0x2b,
		0x15, 0x1e, 0x09, 0x67, 0x1b, 0x3a, 0xf7, 0x79, 0x61, 0xf7, 0x66, 0x27,
		0x6d, 0x27, 0xd6, 0xc1, 0x9d, 0x08, 0xbe, 0x31, 0x14, 0x34, 0xe6, 0x09,
		0x1a, 0xcf, 0x4b, 0xe7, 0xdc, 0x00, 0x0d, 0x3b, 0xbb, 0xc0, 0x4a, 0x0c,
		0xdb, 0x10, 0x16, 0x59, 0x25, 0x21, 0xf3, 0x9c, 0xe2, 0x2b, 0x0a, 0x5b,
		0x3f, 0xf2, 0x44, 0xee, 0x2d, 0x43, 0xe3, 0xe3, 0x25, 0x96, 0x5f, 0xf1,
		0x11, 0xc7, 0xdb, 0xce, 0x96, 0xd8, 0x76, 0x51, 0x8a, 0x34, 0x3e, 0xfa,
		0xc0, 0x01, 0xb2, 0x6a, 0x92, 0x78, 0xa3, 0x37, 0x57, 0xaf, 0x60, 0x63,
		0xb6, 0x9e, 0x2b, 0x12, 0x23, 0x06, 0x8f, 0x23, 0x9f, 0x81, 0xbb, 0xab,
		0x7b, 0x1d, 0xb4, 0x17, 0x2b, 0xf5, 0x03, 0x8d, 0x14, 0xc1, 0xd6, 0x8a,
		0x77, 0x2a, 0x67, 0x9a, 0xd1, 0x32, 0x5c, 0x87, 0x4f, 0xfb, 0xef, 0xdd,
		0x8f, 0x8c, 0x96, 0x19, 0x7d, 0xeb, 0xb3, 0x3c, 0x8e, 0xd5, 0xea, 0xc6,
		0xce, 0xc0, 0x88, 0x9e, 0x0f, 0x44, 0x0e, 0x13, 0xeb, 0x78, 0xbd, 0xdc,
		0xee, 0xe6, 0x55, 0x9d, 0x92, 0x6b, 0xae, 0x55, 0x0f, 0x4b, 0xb9, 0x8f,
		0x27, 0x33, 0xdf, 0x8d, 0x46, 0x61, 0x09, 0x62, 0xbd, 0x05, 0x09, 0xe2,
		0x02, 0x84, 0x87, 0x89, 0x98, 0x81, 0xd2, 0x50, 0x01, 0xd9, 0x35, 0x0d,
		0x53, 0x88, 0x1a, 0xa8, 0x68, 0x23, 0xe1, 0x30, 0xef, 0xd4, 0xa3, 0xda,
		0xa6, 0xa3, 0xf5, 0xb2, 0x97, 0x5c, 0x21, 0x61, 0xaa, 0x03, 0xee, 0x34,
		0x8f, 0xbd, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0xc4, 0x30,
		0x82, 0x01, 0xc0, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01,
		0xff, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x1d, 0x06, 0x03, 0x55,
		0x1d, 0x25, 0x04, 0x16, 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
		0x05, 0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
		0x03, 0x02, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff,
		0x04, 0x02, 0x30, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04,
		0x16, 0x04, 0x14, 0x3b, 0x52, 0x6d, 0xbb, 0x37, 0x04, 0x01, 0x4e, 0xa4,
		0xbf, 0x45, 0x50, 0x94, 0x47, 0x0b, 0xe7, 0xd4, 0xaf, 0x34, 0xe4, 0x30,
		0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
		0xfb, 0x78, 0x4f, 0x12, 0xf9, 0x60, 0x15, 0x83, 0x2c, 0x9f, 0x17, 0x7f,
		0x34, 0x19, 0xb3, 0x2e, 0x36, 0xea, 0x41, 0x89, 0x30, 0x6a, 0x06, 0x08,
		0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x5e, 0x30, 0x5c,
		0x30, 0x26, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01,
		0x86, 0x1a, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x31, 0x32, 0x37,
		0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x3a, 0x34, 0x30, 0x30, 0x32, 0x2f,
		0x6f, 0x63, 0x73, 0x70, 0x30, 0x32, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
		0x05, 0x07, 0x30, 0x02, 0x86, 0x26, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
		0x2f, 0x31, 0x32, 0x37, 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x3a, 0x34,
		0x30, 0x30, 0x30, 0x2f, 0x61, 0x63, 0x6d, 0x65, 0x2f, 0x69, 0x73, 0x73,
		0x75, 0x65, 0x72, 0x2d, 0x63, 0x65, 0x72, 0x74, 0x30, 0x49, 0x06, 0x03,
		0x55, 0x1d, 0x11, 0x04, 0x42, 0x30, 0x40, 0x82, 0x1e, 0x64, 0x6f, 0x6d,
		0x31, 0x2e, 0x61, 0x63, 0x6d, 0x65, 0x74, 0x6f, 0x6f, 0x6c, 0x2d, 0x74,
		0x65, 0x73, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x65, 0x76, 0x65, 0x72, 0x2e,
		0x6e, 0x65, 0x74, 0x82, 0x1e, 0x64, 0x6f, 0x6d, 0x32, 0x2e, 0x61, 0x63,
		0x6d, 0x65, 0x74, 0x6f, 0x6f, 0x6c, 0x2d, 0x74, 0x65, 0x73, 0x74, 0x2e,
		0x64, 0x65, 0x76, 0x65, 0x76, 0x65, 0x72, 0x2e, 0x6e, 0x65, 0x74, 0x30,
		0x27, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x20, 0x30, 0x1e, 0x30, 0x1c,
		0xa0, 0x1a, 0xa0, 0x18, 0x86, 0x16, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
		0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d,
		0x2f, 0x63, 0x72, 0x6c, 0x30, 0x61, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04,
		0x5a, 0x30, 0x58, 0x30, 0x08, 0x06, 0x06, 0x67, 0x81, 0x0c, 0x01, 0x02,
		0x01, 0x30, 0x4c, 0x06, 0x03, 0x2a, 0x03, 0x04, 0x30, 0x45, 0x30, 0x22,
		0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x16,
		0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70,
		0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x1f,
		0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x02, 0x30, 0x13,
		0x0c, 0x11, 0x44, 0x6f, 0x20, 0x57, 0x68, 0x61, 0x74, 0x20, 0x54, 0x68,
		0x6f, 0x75, 0x20, 0x57, 0x69, 0x6c, 0x74, 0x30, 0x0d, 0x06, 0x09, 0x2a,
		0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82,
		0x01, 0x01, 0x00, 0x86, 0x97, 0x21, 0x05, 0x6d, 0x64, 0xfb, 0xe2, 0xeb,
		0x6f, 0x26, 0x82, 0x1b, 0x46, 0x3c, 0x76, 0x92, 0x58, 0xd3, 0x54, 0xc3,
		0x84, 0xac, 0x4d, 0xa0, 0xca, 0xc4, 0x19, 0x37, 0x7b, 0x50, 0x7d, 0x05,
		0xec, 0x0a, 0xfe, 0x90, 0x13, 0xce, 0x71, 0xfd, 0x20, 0x82, 0x5b, 0xd7,
		0xea, 0x07, 0x19, 0xcd, 0xc2, 0x64, 0x20, 0xb4, 0x13, 0x6c, 0x17, 0x2d,
		0xe4, 0xbb, 0xea, 0xb5, 0xaf, 0xa3, 0xfc, 0x93, 0x24, 0xb1, 0xe0, 0x28,
		0x00, 0x5a, 0xf7, 0xd4, 0x65, 0x8f, 0xed, 0x27, 0x5e, 0x3a, 0xc9, 0xa2,
		0xb7, 0x1c, 0xd6, 0x99, 0xb2, 0xfe, 0x32, 0x6d, 0xb9, 0xea, 0x3a, 0x97,
		0x3d, 0x87, 0xb0, 0x52, 0x22, 0xb5, 0x93, 0xd1, 0xe9, 0x98, 0xf4, 0xfd,
		0x09, 0xa8, 0xd2, 0xe9, 0x3f, 0xdf, 0xd9, 0x0d, 0x11, 0xbd, 0x14, 0x20,
		0x44, 0x3e, 0x1e, 0xd8, 0x1e, 0xb5, 0x91, 0x34, 0x4c, 0xb7, 0x7b, 0x78,
		0xa7, 0xbb, 0xb4, 0xff, 0x01, 0x79, 0x3c, 0x3c, 0xec, 0x8f, 0xca, 0x02,
		0xd0, 0x3f, 0xf2, 0x51, 0x20, 0x54, 0xee, 0x27, 0x16, 0x1c, 0xf9, 0x33,
		0xb8, 0xa8, 0x70, 0xfb, 0x38, 0xd8, 0x64, 0xfa, 0x15, 0x77, 0x21, 0x1e,
		0xd0, 0x2a, 0x0b, 0x32, 0xd4, 0xec, 0x90, 0xf6, 0x68, 0xa1, 0x96, 0xf2,
		0x33, 0xe9, 0xe0, 0x17, 0x28, 0x37, 0x06, 0x8c, 0xb5, 0x47, 0x8a, 0x71,
		0xfe, 0x69, 0x9d, 0x57, 0x57, 0xdd, 0xb3, 0x99, 0xc7, 0x75, 0x9f, 0x91,
		0xea, 0x0d, 0xaa, 0x7b, 0xb1, 0x53, 0xec, 0xb0, 0x7c, 0x29, 0x45, 0x6c,
		0x50, 0xc1, 0x32, 0x09, 0x48, 0x83, 0x23, 0x37, 0xae, 0xd5, 0x62, 0xe7,
		0xbd, 0x66, 0xbf, 0xc5, 0x57, 0xf0, 0x05, 0xb2, 0xaf, 0x80, 0xc8, 0xe7,
		0x1e, 0xcd, 0xf5, 0xa8, 0xe0, 0xdb, 0xb1, 0x2c, 0xd1, 0x46, 0x93, 0x60,
		0x5f, 0x43, 0x56, 0x13, 0x5e, 0x23, 0x7b,
	},
	{
		0x30, 0x82, 0x04, 0x8a, 0x30, 0x82, 0x03, 0x72, 0xa0, 0x03, 0x02, 0x01,
		0x02, 0x02, 0x02, 0x12, 0x4d, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
		0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x2b, 0x31, 0x29,
		0x30, 0x27, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x20, 0x63, 0x61, 0x63,
		0x6b, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f,
		0x67, 0x72, 0x61, 0x70, 0x68, 0x65, 0x72, 0x20, 0x66, 0x61, 0x6b, 0x65,
		0x20, 0x52, 0x4f, 0x4f, 0x54, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x35, 0x31,
		0x30, 0x32, 0x31, 0x32, 0x30, 0x31, 0x31, 0x35, 0x32, 0x5a, 0x17, 0x0d,
		0x32, 0x30, 0x31, 0x30, 0x31, 0x39, 0x32, 0x30, 0x31, 0x31, 0x35, 0x32,
		0x5a, 0x30, 0x1f, 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03,
		0x13, 0x14, 0x68, 0x61, 0x70, 0x70, 0x79, 0x20, 0x68, 0x61, 0x63, 0x6b,
		0x65, 0x72, 0x20, 0x66, 0x61, 0x6b, 0x65, 0x20, 0x43, 0x41, 0x30, 0x82,
		0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
		0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82,
		0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xc2, 0x0a, 0x47, 0x79, 0x9a,
		0x05, 0xc5, 0x12, 0xb2, 0x77, 0x17, 0x63, 0x34, 0x13, 0xd7, 0x70, 0xf9,
		0x36, 0xbf, 0x99, 0xde, 0x62, 0xf1, 0x30, 0xc8, 0x77, 0x4d, 0x47, 0x6d,
		0xea, 0xc0, 0x02, 0x9a, 0xa6, 0xc9, 0xd1, 0xbb, 0x51, 0x96, 0x05, 0xdf,
		0x32, 0xd3, 0x4b, 0x33, 0x63, 0x94, 0xd4, 0x8e, 0x9a, 0xdc, 0x9b, 0xbe,
		0xb4, 0x86, 0x52, 0x76, 0x7d, 0xaf, 0xdb, 0x52, 0x41, 0xc2, 0xfc, 0x54,
		0xce, 0x96, 0x50, 0xe3, 0x3c, 0xb6, 0x72, 0x29, 0x88, 0x88, 0xc4, 0x03,
		0x64, 0x24, 0x07, 0x27, 0x0c, 0xc2, 0xf4, 0x66, 0x67, 0xf0, 0x76, 0x96,
		0xd3, 0xdd, 0x62, 0xcf, 0xd1, 0xf4, 0x1a, 0x8d, 0xc0, 0xed, 0x60, 0xd7,
		0xc1, 0x83, 0x66, 0xb1, 0xd2, 0xcd, 0x46, 0x2d, 0x34, 0xa3, 0x5e, 0x14,
		0x8e, 0x86, 0x95, 0xa9, 0xa3, 0xec, 0x62, 0xb6, 0x56, 0xbd, 0x12, 0x9a,
		0x21, 0x1a, 0x9a, 0x53, 0x48, 0x47, 0x99, 0x2d, 0x00, 0x5b, 0x04, 0x12,
		0xbc, 0xdf, 0xfd, 0xde, 0x23, 0x08, 0x5e, 0xec, 0xa2, 0xc3, 0x2c, 0x26,
		0x93, 0x02, 0x9b, 0x5a, 0x79, 0xf1, 0x09, 0x0f, 0xe0, 0xb1, 0xcb, 0x4a,
		0x15, 0x4b, 0x5c, 0x36, 0xbc, 0x04, 0xc7, 0xd5, 0xa0, 0x8f, 0xa2, 0xa5,
		0x87, 0x00, 0xd3, 0xc8, 0x8d, 0x50, 0x59, 0x20, 0x5b, 0xc5, 0x56, 0x0d,
		0xc9, 0x48, 0x0f, 0x17, 0x32, 0xb1, 0xad, 0x29, 0xb0, 0x30, 0xed, 0x32,
		0x35, 0xf7, 0xfb, 0x86, 0x8f, 0x90, 0x4f, 0xdc, 0x79, 0xf9, 0x8f, 0xfb,
		0x5c, 0x4e, 0x7d, 0x4b, 0x83, 0x1c, 0xe1, 0x95, 0xf1, 0x71, 0x72, 0x9e,
		0xc3, 0xf8, 0x12, 0x94, 0xdf, 0x54, 0xe6, 0x6b, 0xd3, 0xf8, 0x3d, 0x81,
		0x84, 0x3b, 0x64, 0x0a, 0xea, 0x5d, 0x7e, 0xc6, 0x4d, 0x09, 0x05, 0xa9,
		0xdb, 0xb0, 0x3e, 0x6f, 0xf0, 0xe6, 0xac, 0x52, 0x3d, 0x36, 0xab, 0x02,
		0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0xc2, 0x30, 0x82, 0x01, 0xbe,
		0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08,
		0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x43, 0x06, 0x03,
		0x55, 0x1d, 0x1e, 0x04, 0x3c, 0x30, 0x3a, 0xa1, 0x38, 0x30, 0x06, 0x82,
		0x04, 0x2e, 0x6d, 0x69, 0x6c, 0x30, 0x0a, 0x87, 0x08, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x22, 0x87, 0x20, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f,
		0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x7f, 0x06,
		0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x73, 0x30,
		0x71, 0x30, 0x32, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30,
		0x01, 0x86, 0x26, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x69, 0x73,
		0x72, 0x67, 0x2e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x69, 0x64, 0x2e, 0x6f,
		0x63, 0x73, 0x70, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73,
		0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x3b, 0x06, 0x08, 0x2b, 0x06, 0x01,
		0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x2f, 0x68, 0x74, 0x74, 0x70, 0x3a,
		0x2f, 0x2f, 0x61, 0x70, 0x70, 0x73, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74,
		0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x6f, 0x6f,
		0x74, 0x73, 0x2f, 0x64, 0x73, 0x74, 0x72, 0x6f, 0x6f, 0x74, 0x63, 0x61,
		0x78, 0x33, 0x2e, 0x70, 0x37, 0x63, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d,
		0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xe9, 0xa4, 0x3f, 0xee, 0x9e,
		0xa5, 0xe6, 0xf2, 0xd5, 0xd7, 0x79, 0x60, 0x3c, 0x93, 0xa6, 0x2e, 0x24,
		0x8e, 0x97, 0xaa, 0x30, 0x54, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x4d,
		0x30, 0x4b, 0x30, 0x08, 0x06, 0x06, 0x67, 0x81, 0x0c, 0x01, 0x02, 0x01,
		0x30, 0x3f, 0x06, 0x0b, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0xdf, 0x13,
		0x01, 0x01, 0x01, 0x30, 0x30, 0x30, 0x2e, 0x06, 0x08, 0x2b, 0x06, 0x01,
		0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a,
		0x2f, 0x2f, 0x63, 0x70, 0x73, 0x2e, 0x72, 0x6f, 0x6f, 0x74, 0x2d, 0x78,
		0x31, 0x2e, 0x6c, 0x65, 0x74, 0x73, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70,
		0x74, 0x2e, 0x6f, 0x72, 0x67, 0x30, 0x3c, 0x06, 0x03, 0x55, 0x1d, 0x1f,
		0x04, 0x35, 0x30, 0x33, 0x30, 0x31, 0xa0, 0x2f, 0xa0, 0x2d, 0x86, 0x2b,
		0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x69,
		0x64, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d,
		0x2f, 0x44, 0x53, 0x54, 0x52, 0x4f, 0x4f, 0x54, 0x43, 0x41, 0x58, 0x33,
		0x43, 0x52, 0x4c, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x1d, 0x06, 0x03, 0x55,
		0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xfb, 0x78, 0x4f, 0x12, 0xf9, 0x60,
		0x15, 0x83, 0x2c, 0x9f, 0x17, 0x7f, 0x34, 0x19, 0xb3, 0x2e, 0x36, 0xea,
		0x41, 0x89, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
		0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x0d, 0x18,
		0x01, 0xe2, 0xd7, 0x3a, 0x49, 0x71, 0xe2, 0x18, 0x42, 0x8a, 0x45, 0x14,
		0x97, 0xe0, 0x5d, 0x9c, 0x57, 0xe7, 0xd6, 0x0d, 0x16, 0xe4, 0x08, 0x90,
		0x2d, 0x53, 0x48, 0x38, 0xbe, 0x8f, 0x9e, 0xa5, 0xee, 0xd3, 0x08, 0xe7,
		0x84, 0xdc, 0xa1, 0xa9, 0xdc, 0x27, 0x7e, 0x16, 0x0c, 0x9e, 0x8c, 0xb8,
		0x89, 0xd4, 0x61, 0xe2, 0x50, 0x7a, 0xa7, 0x3f, 0x06, 0x7f, 0xda, 0x67,
		0x94, 0xb7, 0x7f, 0x0e, 0x75, 0x92, 0x57, 0x78, 0x12, 0xfb, 0xf2, 0x3f,
		0x98, 0x09, 0x75, 0x74, 0x29, 0x0a, 0x6f, 0x2e, 0x87, 0xd9, 0x5e, 0xfd,
		0xd1, 0xee, 0x88, 0x1e, 0x62, 0x0a, 0xd8, 0xa6, 0x26, 0xde, 0x39, 0xbe,
		0x53, 0xef, 0x85, 0x21, 0xd1, 0xa9, 0x05, 0xdb, 0x10, 0x4d, 0x27, 0x66,
		0x89, 0x7f, 0xeb, 0x03, 0x2b, 0xb1, 0x30, 0x33, 0x34, 0x69, 0xd3, 0x24,
		0x34, 0x1c, 0x13, 0x7d, 0x09, 0x99, 0x40, 0x2c, 0xfa, 0x9c, 0x61, 0xf0,
		0xd5, 0x07, 0x12, 0x3d, 0x93, 0x2f, 0x66, 0x9b, 0x02, 0xf1, 0x29, 0x2f,
		0x7a, 0x4c, 0xf1, 0xb2, 0x31, 0x75, 0xa2, 0xd3, 0xab, 0x31, 0x43, 0xcd,
		0x3d, 0x0b, 0xed, 0x4d, 0x6a, 0xd5, 0xc7, 0xc1, 0xa5, 0x47, 0x6a, 0x9f,
		0xc7, 0xfe, 0x31, 0x6d, 0x06, 0xb5, 0xbf, 0x67, 0xeb, 0x36, 0xf1, 0x41,
		0x0a, 0x63, 0xb9, 0xf6, 0x0a, 0x33, 0xfa, 0x39, 0xd6, 0xbd, 0xf4, 0xed,
		0x8f, 0x63, 0x63, 0xc0, 0x36, 0x7b, 0xbe, 0x53, 0x01, 0xb0, 0xf9, 0xb5,
		0xe9, 0xd6, 0xca, 0x60, 0x2f, 0x38, 0xd2, 0xeb, 0xd1, 0xa1, 0x98, 0xf1,
		0xaa, 0xc7, 0x5c, 0xdc, 0x28, 0x42, 0x66, 0x3a, 0xa2, 0x98, 0x5a, 0xa5,
		0x34, 0x6f, 0xf1, 0xa0, 0xf0, 0x3c, 0xf9, 0xd4, 0xe2, 0x71, 0x9c, 0xc2,
		0x5c, 0x4f, 0x62, 0x8c, 0xf2, 0x1c, 0xbd, 0x6e, 0xb2, 0xd5, 0xa6, 0xb7,
		0x6c, 0x6c,
	},
}

func TestLoadCertificates(t *testing.T) {
	b, err := LoadCertificates([]byte(testCerts))
	if err != nil {
		t.Fatalf("cannot load certificates")
	}

	if !reflect.DeepEqual(b, testCertsDER) {
		t.Fatalf("certificate load mismatch")
	}
}

const testKey = `-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAwpBqfaZxkAhaq7snn/qf4pDnbX5WWwkR7fXz2Esl/NNvGkPF
qD8OImjbFyXiNl4QCSsVHglnGzr3eWH3ZidtJ9bBnQi+MRQ05gkaz0vn3AANO7vA
SgzbEBZZJSHznOIrCls/8kTuLUPj4yWWX/ERx9vOlth2UYo0PvrAAbJqknijN1ev
YGO2nisSIwaPI5+Bu6t7HbQXK/UDjRTB1op3Kmea0TJch0/7792PjJYZfeuzPI7V
6sbOwIieD0QOE+t4vdzu5lWdkmuuVQ9LuY8nM9+NRmEJYr0FCeIChIeJmIHSUAHZ
NQ1TiBqoaCPhMO/Uo9qmo/Wyl1whYaoD7jSPvQIDAQABAoIBAH69WlE9Ui6T8pR5
lsdUmEAbSlX9/TzR/Lb5B332/ejixjXivefqI0fw6/75M5Fc1q9SPDBTybFoSPru
AR2vQyC3eWnU3yfTVN4gQjGU7ZVXB0fI9uqF01F4bVuN8UZZ4dWeOVqU4l3kIpe9
zWX0ADQjkECdAv38vCnmZ5rzYQ7FmPoZse8fC7TqJIqvMN2lkBQd/7ecfSGiDsxS
jdV/a2gE+AuS1d06yfLiu8UuRYe7le1VEx84NHBAQv71IG1kc+9bKWqOlXPXvS7o
WQi976wETxbqEbZLtQlHhX7ND/Svof+O/IwbfHcfz1qhMGZ8wP4CeuLQGXpVqSpc
PWTR/bUCgYEAy6zdOmvpj/Ss6o2oHWqXek6PKWVmnE13NZ45GrWaBT8tG9znJRoG
qA3Cj5BedJSzCEfrVZ4Yi29PrRl7HbHYEcIiJZ1rwdmPmlRK/VWgk8RpBAzT/ilS
90jTXBPlA/WvzMgwtO0hJEbnpvH5EB2WviyNWgvRhwdzPWqJVEy/S3MCgYEA9IxW
2VU1Rnx1mcudl0Y68pcLU25pXA7VsA5IsyCk1a5rwecgRDF3dVJ1lJGp8+Xf4/Wo
eDhqk1tdTAp0Uy+GfJcTkrAJZO1jeYoJj6Hy4QT50xPNMQZHZ0uOkIbLfHHcXJHa
9qcEIzKpcPiq5cD0PYqJQO3f3gw5V/aLKCTDTA8CgYAYQmi/UqcpLF2EOocxqcaN
HNpUde145Ik0a7olgkfsJBA9Z1xowObWEX2BGBMIE8YXUGmpcwE9am61EXnmmY5A
3zyt+kgheMZv/WZJMm/D6fsQLm75sPZe2d/C8eOvSw47eATFKBFwfrmM2vltf/i6
ghf8B7hXOv3w7MWasuF+HQKBgEixQsu9uWVnb6m0zfZ+qN0dqv807dqwijKYPGIK
zRS7kUqFQqEityjHxy3Pkt5uMXxYtKhv1LZSzUviO6vSj76PRgEvlMtMiWpCbw8k
C8d5rC1jUHZHMIhy/EDX4LrwOZnGvXjeMqunzphHQr2i+rckbCJB02704ULVhY38
R5VfAoGBAISqeTh28iF9SirK18xpsW6c6j+x6qfjs8Rr6pPAnO1vovUCH6vlxV4I
RLeWOCS9ROFhbef4WqWpa82vGd0OxoUBirPRWRFyt0pgH9qAmwqD2YN8KFCyPztD
xtiaTxLKSHYuEVxbJZJmDNkjDEtGk7hVzOQ0+GO+Tvknkp/kkHsn
-----END RSA PRIVATE KEY-----`

const testKeyPKCS8 = `-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDCkGp9pnGQCFqr
uyef+p/ikOdtflZbCRHt9fPYSyX8028aQ8WoPw4iaNsXJeI2XhAJKxUeCWcbOvd5
YfdmJ20n1sGdCL4xFDTmCRrPS+fcAA07u8BKDNsQFlklIfOc4isKWz/yRO4tQ+Pj
JZZf8RHH286W2HZRijQ++sABsmqSeKM3V69gY7aeKxIjBo8jn4G7q3sdtBcr9QON
FMHWincqZ5rRMlyHT/vv3Y+Mlhl967M8jtXqxs7AiJ4PRA4T63i93O7mVZ2Sa65V
D0u5jycz341GYQlivQUJ4gKEh4mYgdJQAdk1DVOIGqhoI+Ew79Sj2qaj9bKXXCFh
qgPuNI+9AgMBAAECggEAfr1aUT1SLpPylHmWx1SYQBtKVf39PNH8tvkHffb96OLG
NeK95+ojR/Dr/vkzkVzWr1I8MFPJsWhI+u4BHa9DILd5adTfJ9NU3iBCMZTtlVcH
R8j26oXTUXhtW43xRlnh1Z45WpTiXeQil73NZfQANCOQQJ0C/fy8KeZnmvNhDsWY
+hmx7x8LtOokiq8w3aWQFB3/t5x9IaIOzFKN1X9raAT4C5LV3TrJ8uK7xS5Fh7uV
7VUTHzg0cEBC/vUgbWRz71spao6Vc9e9LuhZCL3vrARPFuoRtku1CUeFfs0P9K+h
/478jBt8dx/PWqEwZnzA/gJ64tAZelWpKlw9ZNH9tQKBgQDLrN06a+mP9Kzqjagd
apd6To8pZWacTXc1njkatZoFPy0b3OclGgaoDcKPkF50lLMIR+tVnhiLb0+tGXsd
sdgRwiIlnWvB2Y+aVEr9VaCTxGkEDNP+KVL3SNNcE+UD9a/MyDC07SEkRuem8fkQ
HZa+LI1aC9GHB3M9aolUTL9LcwKBgQD0jFbZVTVGfHWZy52XRjrylwtTbmlcDtWw
DkizIKTVrmvB5yBEMXd1UnWUkanz5d/j9ah4OGqTW11MCnRTL4Z8lxOSsAlk7WN5
igmPofLhBPnTE80xBkdnS46Qhst8cdxckdr2pwQjMqlw+KrlwPQ9iolA7d/eDDlX
9osoJMNMDwKBgBhCaL9SpyksXYQ6hzGpxo0c2lR17XjkiTRruiWCR+wkED1nXGjA
5tYRfYEYEwgTxhdQaalzAT1qbrUReeaZjkDfPK36SCF4xm/9Zkkyb8Pp+xAubvmw
9l7Z38Lx469LDjt4BMUoEXB+uYza+W1/+LqCF/wHuFc6/fDsxZqy4X4dAoGASLFC
y725ZWdvqbTN9n6o3R2q/zTt2rCKMpg8YgrNFLuRSoVCoSK3KMfHLc+S3m4xfFi0
qG/UtlLNS+I7q9KPvo9GAS+Uy0yJakJvDyQLx3msLWNQdkcwiHL8QNfguvA5mca9
eN4yq6fOmEdCvaL6tyRsIkHTbvThQtWFjfxHlV8CgYEAhKp5OHbyIX1KKsrXzGmx
bpzqP7Hqp+OzxGvqk8Cc7W+i9QIfq+XFXghEt5Y4JL1E4WFt5/hapalrza8Z3Q7G
hQGKs9FZEXK3SmAf2oCbCoPZg3woULI/O0PG2JpPEspIdi4RXFslkmYM2SMMS0aT
uFXM5DT4Y75O+SeSn+SQeyc=
-----END PRIVATE KEY-----`

var testKeyN, _ = big.NewInt(0).SetString("00c2906a7da67190085aabbb279ffa9fe290e76d7e565b0911edf5f3d84b25fcd36f1a43c5a83f0e2268db1725e2365e10092b151e09671b3af77961f766276d27d6c19d08be311434e6091acf4be7dc000d3bbbc04a0cdb1016592521f39ce22b0a5b3ff244ee2d43e3e325965ff111c7dbce96d876518a343efac001b26a9278a33757af6063b69e2b1223068f239f81bbab7b1db4172bf5038d14c1d68a772a679ad1325c874ffbefdd8f8c96197debb33c8ed5eac6cec0889e0f440e13eb78bddceee6559d926bae550f4bb98f2733df8d46610962bd0509e2028487899881d25001d9350d53881aa86823e130efd4a3daa6a3f5b2975c2161aa03ee348fbd", 16)

var testKeyD, _ = big.NewInt(0).SetString("7ebd5a513d522e93f2947996c75498401b4a55fdfd3cd1fcb6f9077df6fde8e2c635e2bde7ea2347f0ebfef933915cd6af523c3053c9b16848faee011daf4320b77969d4df27d354de20423194ed95570747c8f6ea85d351786d5b8df14659e1d59e395a94e25de42297bdcd65f400342390409d02fdfcbc29e6679af3610ec598fa19b1ef1f0bb4ea248aaf30dda590141dffb79c7d21a20ecc528dd57f6b6804f80b92d5dd3ac9f2e2bbc52e4587bb95ed55131f3834704042fef5206d6473ef5b296a8e9573d7bd2ee85908bdefac044f16ea11b64bb50947857ecd0ff4afa1ff8efc8c1b7c771fcf5aa130667cc0fe027ae2d0197a55a92a5c3d64d1fdb5", 16)

var testKeyPrime1, _ = big.NewInt(0).SetString("00cbacdd3a6be98ff4acea8da81d6a977a4e8f2965669c4d77359e391ab59a053f2d1bdce7251a06a80dc28f905e7494b30847eb559e188b6f4fad197b1db1d811c222259d6bc1d98f9a544afd55a093c469040cd3fe2952f748d35c13e503f5afccc830b4ed212446e7a6f1f9101d96be2c8d5a0bd18707733d6a89544cbf4b73", 16)

var testKeyPrime2, _ = big.NewInt(0).
	SetString("00f48c56d95535467c7599cb9d97463af2970b536e695c0ed5b00e48b320a4d5ae6bc1e7204431777552759491a9f3e5dfe3f5a878386a935b5d4c0a74532f867c971392b00964ed63798a098fa1f2e104f9d313cd310647674b8e9086cb7c71dc5c91daf6a7042332a970f8aae5c0f43d8a8940eddfde0c3957f68b2824c34c0f", 16)

var testKeyDp, _ = big.NewInt(0).SetString("184268bf52a7292c5d843a8731a9c68d1cda5475ed78e489346bba258247ec24103d675c68c0e6d6117d8118130813c6175069a973013d6a6eb51179e6998e40df3cadfa482178c66ffd6649326fc3e9fb102e6ef9b0f65ed9dfc2f1e3af4b0e3b7804c52811707eb98cdaf96d7ff8ba8217fc07b8573afdf0ecc59ab2e17e1d", 16)

var testKeyDq, _ = big.NewInt(0).SetString("48b142cbbdb965676fa9b4cdf67ea8dd1daaff34eddab08a32983c620acd14bb914a8542a122b728c7c72dcf92de6e317c58b4a86fd4b652cd4be23babd28fbe8f46012f94cb4c896a426f0f240bc779ac2d63507647308872fc40d7e0baf03999c6bd78de32aba7ce984742bda2fab7246c2241d36ef4e142d5858dfc47955f", 16)

var testKeyQinv, _ = big.NewInt(0).SetString("0084aa793876f2217d4a2acad7cc69b16e9cea3fb1eaa7e3b3c46bea93c09ced6fa2f5021fabe5c55e0844b7963824bd44e1616de7f85aa5a96bcdaf19dd0ec685018ab3d1591172b74a601fda809b0a83d9837c2850b23f3b43c6d89a4f12ca48762e115c5b2592660cd9230c4b4693b855cce434f863be4ef927929fe4907b27", 16)

var testKeyValue = &rsa.PrivateKey{
	PublicKey: rsa.PublicKey{
		N: testKeyN,
		E: 0x10001,
	},
	D: testKeyD,
	Primes: []*big.Int{
		testKeyPrime1, testKeyPrime2,
	},
	Precomputed: rsa.PrecomputedValues{
		Dp:        testKeyDp,
		Dq:        testKeyDq,
		Qinv:      testKeyQinv,
		CRTValues: []rsa.CRTValue{},
	},
}

const testECKey = `-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIABVf3JmY6Fs0MpQwXlUCw0T27BO+hjjr93v/nLT9PrZoAoGCCqGSM49
AwEHoUQDQgAEkDk1q0XGYa6flpAaBVHEI5UStWvdewAHpIbN+PpOlKNgeK1Xu0nw
Pv7jwLK+95tYBYbVu1gUnQ+OjWpxyuITaA==
-----END EC PRIVATE KEY-----`

const testECKeyPKCS8 = `-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgAFV/cmZjoWzQylDB
eVQLDRPbsE76GOOv3e/+ctP0+tmhRANCAASQOTWrRcZhrp+WkBoFUcQjlRK1a917
AAekhs34+k6Uo2B4rVe7SfA+/uPAsr73m1gFhtW7WBSdD46NanHK4hNo
-----END PRIVATE KEY-----`

var testECKeyX, _ = big.NewInt(0).SetString("903935ab45c661ae9f96901a0551c4239512b56bdd7b0007a486cdf8fa4e94a3", 16)
var testECKeyY, _ = big.NewInt(0).SetString("6078ad57bb49f03efee3c0b2bef79b580586d5bb58149d0f8e8d6a71cae21368", 16)
var testECKeyD, _ = big.NewInt(0).SetString("557f726663a16cd0ca50c179540b0d13dbb04efa18e3afddeffe72d3f4fad9", 16)

var testECKeyValue = &ecdsa.PrivateKey{
	PublicKey: ecdsa.PublicKey{
		Curve: elliptic.P256(),
		X:     testECKeyX,
		Y:     testECKeyY,
	},
	D: testECKeyD,
}

func TestLoadKey(t *testing.T) {
	pk, err := LoadPrivateKey([]byte(testKey))
	if err != nil {
		t.Fatalf("failed to load private key: %v", err)
	}

	if !reflect.DeepEqual(testKeyValue, pk) {
		t.Fatalf("key mismatch: %#v %#v", testKeyValue, pk)
	}

	pk2, err := LoadPrivateKey([]byte(testKeyPKCS8))
	if err != nil {
		t.Fatalf("failed to load private key: %v", err)
	}

	if !reflect.DeepEqual(testKeyValue, pk2) {
		t.Fatalf("key mismatch: %#v %#v", testKeyValue, pk2)
	}

	epk, err := LoadPrivateKey([]byte(testECKey))
	if err != nil {
		t.Fatalf("failed to load EC private key: %v", err)
	}

	if !reflect.DeepEqual(epk, testECKeyValue) {
		t.Fatalf("EC key mismatch: %#v %#v", epk, testECKeyValue)
	}

	epk2, err := LoadPrivateKey([]byte(testECKeyPKCS8))
	if err != nil {
		t.Fatalf("failed to load EC private key: %v", err)
	}

	if !reflect.DeepEqual(epk2, testECKeyValue) {
		t.Fatalf("EC key mismatch: %#v %#v", epk2, testECKeyValue)
	}

	b := bytes.Buffer{}
	err = SavePrivateKey(&b, pk)
	if err != nil {
		t.Fatalf("%v", err)
	}
	pkc, err := LoadPrivateKey(b.Bytes())
	if err != nil {
		t.Fatalf("%v", err)
	}
	if !reflect.DeepEqual(pk, pkc) {
		t.Fatalf("mismatch after save-load")
	}

	b = bytes.Buffer{}
	err = SavePrivateKey(&b, epk)
	if err != nil {
		t.Fatalf("%v", err)
	}
	epkc, err := LoadPrivateKey(b.Bytes())
	if err != nil {
		t.Fatalf("%v", err)
	}
	if !reflect.DeepEqual(epk, epkc) {
		t.Fatalf("mismatch after save-load")
	}
}

const testCSR = `-----BEGIN CERTIFICATE REQUEST-----
MIICWzCCAUMCAQAwFjEUMBIGA1UEAwwLZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3
DQEBAQUAA4IBDwAwggEKAoIBAQDCkGp9pnGQCFqruyef+p/ikOdtflZbCRHt9fPY
SyX8028aQ8WoPw4iaNsXJeI2XhAJKxUeCWcbOvd5YfdmJ20n1sGdCL4xFDTmCRrP
S+fcAA07u8BKDNsQFlklIfOc4isKWz/yRO4tQ+PjJZZf8RHH286W2HZRijQ++sAB
smqSeKM3V69gY7aeKxIjBo8jn4G7q3sdtBcr9QONFMHWincqZ5rRMlyHT/vv3Y+M
lhl967M8jtXqxs7AiJ4PRA4T63i93O7mVZ2Sa65VD0u5jycz341GYQlivQUJ4gKE
h4mYgdJQAdk1DVOIGqhoI+Ew79Sj2qaj9bKXXCFhqgPuNI+9AgMBAAGgADANBgkq
hkiG9w0BAQsFAAOCAQEAGwrSUMmte+rXVUVsYS7cqN0xJFOc18vuMDUezAsAw8Ye
UDhivw2wsPTlPBl3zpVavlGSM5ZPWgv4osZtDeS/VeL+ow/7wVShlc2rbyuXTwoq
Lh4+Oe4svEEfGwvia5Ui4XA2eFFLSaTVM+FWGZNUXoB++bS831ro2fffoI3jrjDz
0edY1zhsjaV9Fej9k37O/1GhkRfTq0WMAnX/VP6L/2Gjs2ZwvAwCItUpCwPw1B3Q
h+/TTT56DupPyRFI1ZmbpX6Rp/A0gL+ykqpjASJj1ai+jkBXiDz/I4LJ2oUhtOxJ
vGQkX0wJF929X+IQlURO6rP5ET9tzmF4S9/F/RA1kw==
-----END CERTIFICATE REQUEST-----`

var testCSRDER = []byte{
	0x30, 0x82, 0x02, 0x5b, 0x30, 0x82, 0x01, 0x43, 0x02, 0x01, 0x00, 0x30,
	0x16, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0b,
	0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30,
	0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
	0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30,
	0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xc2, 0x90, 0x6a, 0x7d,
	0xa6, 0x71, 0x90, 0x08, 0x5a, 0xab, 0xbb, 0x27, 0x9f, 0xfa, 0x9f, 0xe2,
	0x90, 0xe7, 0x6d, 0x7e, 0x56, 0x5b, 0x09, 0x11, 0xed, 0xf5, 0xf3, 0xd8,
	0x4b, 0x25, 0xfc, 0xd3, 0x6f, 0x1a, 0x43, 0xc5, 0xa8, 0x3f, 0x0e, 0x22,
	0x68, 0xdb, 0x17, 0x25, 0xe2, 0x36, 0x5e, 0x10, 0x09, 0x2b, 0x15, 0x1e,
	0x09, 0x67, 0x1b, 0x3a, 0xf7, 0x79, 0x61, 0xf7, 0x66, 0x27, 0x6d, 0x27,
	0xd6, 0xc1, 0x9d, 0x08, 0xbe, 0x31, 0x14, 0x34, 0xe6, 0x09, 0x1a, 0xcf,
	0x4b, 0xe7, 0xdc, 0x00, 0x0d, 0x3b, 0xbb, 0xc0, 0x4a, 0x0c, 0xdb, 0x10,
	0x16, 0x59, 0x25, 0x21, 0xf3, 0x9c, 0xe2, 0x2b, 0x0a, 0x5b, 0x3f, 0xf2,
	0x44, 0xee, 0x2d, 0x43, 0xe3, 0xe3, 0x25, 0x96, 0x5f, 0xf1, 0x11, 0xc7,
	0xdb, 0xce, 0x96, 0xd8, 0x76, 0x51, 0x8a, 0x34, 0x3e, 0xfa, 0xc0, 0x01,
	0xb2, 0x6a, 0x92, 0x78, 0xa3, 0x37, 0x57, 0xaf, 0x60, 0x63, 0xb6, 0x9e,
	0x2b, 0x12, 0x23, 0x06, 0x8f, 0x23, 0x9f, 0x81, 0xbb, 0xab, 0x7b, 0x1d,
	0xb4, 0x17, 0x2b, 0xf5, 0x03, 0x8d, 0x14, 0xc1, 0xd6, 0x8a, 0x77, 0x2a,
	0x67, 0x9a, 0xd1, 0x32, 0x5c, 0x87, 0x4f, 0xfb, 0xef, 0xdd, 0x8f, 0x8c,
	0x96, 0x19, 0x7d, 0xeb, 0xb3, 0x3c, 0x8e, 0xd5, 0xea, 0xc6, 0xce, 0xc0,
	0x88, 0x9e, 0x0f, 0x44, 0x0e, 0x13, 0xeb, 0x78, 0xbd, 0xdc, 0xee, 0xe6,
	0x55, 0x9d, 0x92, 0x6b, 0xae, 0x55, 0x0f, 0x4b, 0xb9, 0x8f, 0x27, 0x33,
	0xdf, 0x8d, 0x46, 0x61, 0x09, 0x62, 0xbd, 0x05, 0x09, 0xe2, 0x02, 0x84,
	0x87, 0x89, 0x98, 0x81, 0xd2, 0x50, 0x01, 0xd9, 0x35, 0x0d, 0x53, 0x88,
	0x1a, 0xa8, 0x68, 0x23, 0xe1, 0x30, 0xef, 0xd4, 0xa3, 0xda, 0xa6, 0xa3,
	0xf5, 0xb2, 0x97, 0x5c, 0x21, 0x61, 0xaa, 0x03, 0xee, 0x34, 0x8f, 0xbd,
	0x02, 0x03, 0x01, 0x00, 0x01, 0xa0, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a,
	0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82,
	0x01, 0x01, 0x00, 0x1b, 0x0a, 0xd2, 0x50, 0xc9, 0xad, 0x7b, 0xea, 0xd7,
	0x55, 0x45, 0x6c, 0x61, 0x2e, 0xdc, 0xa8, 0xdd, 0x31, 0x24, 0x53, 0x9c,
	0xd7, 0xcb, 0xee, 0x30, 0x35, 0x1e, 0xcc, 0x0b, 0x00, 0xc3, 0xc6, 0x1e,
	0x50, 0x38, 0x62, 0xbf, 0x0d, 0xb0, 0xb0, 0xf4, 0xe5, 0x3c, 0x19, 0x77,
	0xce, 0x95, 0x5a, 0xbe, 0x51, 0x92, 0x33, 0x96, 0x4f, 0x5a, 0x0b, 0xf8,
	0xa2, 0xc6, 0x6d, 0x0d, 0xe4, 0xbf, 0x55, 0xe2, 0xfe, 0xa3, 0x0f, 0xfb,
	0xc1, 0x54, 0xa1, 0x95, 0xcd, 0xab, 0x6f, 0x2b, 0x97, 0x4f, 0x0a, 0x2a,
	0x2e, 0x1e, 0x3e, 0x39, 0xee, 0x2c, 0xbc, 0x41, 0x1f, 0x1b, 0x0b, 0xe2,
	0x6b, 0x95, 0x22, 0xe1, 0x70, 0x36, 0x78, 0x51, 0x4b, 0x49, 0xa4, 0xd5,
	0x33, 0xe1, 0x56, 0x19, 0x93, 0x54, 0x5e, 0x80, 0x7e, 0xf9, 0xb4, 0xbc,
	0xdf, 0x5a, 0xe8, 0xd9, 0xf7, 0xdf, 0xa0, 0x8d, 0xe3, 0xae, 0x30, 0xf3,
	0xd1, 0xe7, 0x58, 0xd7, 0x38, 0x6c, 0x8d, 0xa5, 0x7d, 0x15, 0xe8, 0xfd,
	0x93, 0x7e, 0xce, 0xff, 0x51, 0xa1, 0x91, 0x17, 0xd3, 0xab, 0x45, 0x8c,
	0x02, 0x75, 0xff, 0x54, 0xfe, 0x8b, 0xff, 0x61, 0xa3, 0xb3, 0x66, 0x70,
	0xbc, 0x0c, 0x02, 0x22, 0xd5, 0x29, 0x0b, 0x03, 0xf0, 0xd4, 0x1d, 0xd0,
	0x87, 0xef, 0xd3, 0x4d, 0x3e, 0x7a, 0x0e, 0xea, 0x4f, 0xc9, 0x11, 0x48,
	0xd5, 0x99, 0x9b, 0xa5, 0x7e, 0x91, 0xa7, 0xf0, 0x34, 0x80, 0xbf, 0xb2,
	0x92, 0xaa, 0x63, 0x01, 0x22, 0x63, 0xd5, 0xa8, 0xbe, 0x8e, 0x40, 0x57,
	0x88, 0x3c, 0xff, 0x23, 0x82, 0xc9, 0xda, 0x85, 0x21, 0xb4, 0xec, 0x49,
	0xbc, 0x64, 0x24, 0x5f, 0x4c, 0x09, 0x17, 0xdd, 0xbd, 0x5f, 0xe2, 0x10,
	0x95, 0x44, 0x4e, 0xea, 0xb3, 0xf9, 0x11, 0x3f, 0x6d, 0xce, 0x61, 0x78,
	0x4b, 0xdf, 0xc5, 0xfd, 0x10, 0x35, 0x93,
}

func TestLoadCSR(t *testing.T) {
	b, err := LoadCSR([]byte(testCSR))
	if err != nil {
		t.Fatalf("load csr")
	}

	if !reflect.DeepEqual(b, testCSRDER) {
		t.Fatalf("bad csr")
	}
}
