github.com/gravitational/teleport/api@v0.0.0-20240507183017-3110591cbafc/utils/keys/privatekey_test.go (about) 1 /* 2 Copyright 2022 Gravitational, Inc. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package keys 18 19 import ( 20 "bytes" 21 "crypto" 22 "crypto/ecdsa" 23 "crypto/ed25519" 24 "crypto/elliptic" 25 "crypto/rand" 26 "crypto/rsa" 27 "crypto/tls" 28 "encoding/pem" 29 "testing" 30 31 "github.com/stretchr/testify/require" 32 ) 33 34 func TestMarshalAndParsePrivateKey(t *testing.T) { 35 rsaKey, err := rsa.GenerateKey(rand.Reader, 1024) 36 require.NoError(t, err) 37 ecKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) 38 require.NoError(t, err) 39 _, edKey, err := ed25519.GenerateKey(rand.Reader) 40 require.NoError(t, err) 41 42 for keyType, key := range map[string]crypto.Signer{ 43 "rsa": rsaKey, 44 "ecdsa": ecKey, 45 "ed25519": edKey, 46 } { 47 t.Run(keyType, func(t *testing.T) { 48 keyPEM, err := MarshalPrivateKey(key) 49 require.NoError(t, err) 50 gotKey, err := ParsePrivateKey(keyPEM) 51 require.NoError(t, err) 52 require.Equal(t, key, gotKey.Signer) 53 }) 54 } 55 } 56 57 // TestX509KeyPair tests that X509KeyPair returns the same value as tls.X509KeyPair. 58 func TestX509KeyPair(t *testing.T) { 59 for _, tc := range []struct { 60 desc string 61 keyPEM []byte 62 certPEM []byte 63 }{ 64 { 65 desc: "rsa cert", 66 keyPEM: rsaKeyPEM, 67 certPEM: rsaCertPEM, 68 }, { 69 desc: "rsa certs", 70 keyPEM: rsaKeyPEM, 71 certPEM: func() []byte { 72 // encode two certs into certPEM. 73 rsaCertPEMDuplicated := new(bytes.Buffer) 74 der, _ := pem.Decode(rsaCertPEM) 75 pem.Encode(rsaCertPEMDuplicated, der) 76 pem.Encode(rsaCertPEMDuplicated, der) 77 return rsaCertPEMDuplicated.Bytes() 78 }(), 79 }, 80 } { 81 t.Run(tc.desc, func(t *testing.T) { 82 expectCert, err := tls.X509KeyPair(tc.certPEM, tc.keyPEM) 83 require.NoError(t, err) 84 85 tlsCert, err := X509KeyPair(tc.certPEM, tc.keyPEM) 86 require.NoError(t, err) 87 88 require.Equal(t, expectCert, tlsCert) 89 }) 90 } 91 } 92 93 var ( 94 // generated with `openssl req -x509 -out rsa.crt -keyout rsa.key -newkey rsa:2048 -nodes -sha256` 95 rsaKeyPEM = []byte(`-----BEGIN PRIVATE KEY----- 96 MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCudYRUc0u2xdQi 97 wzEckPP9lVnXmC2b8vkstKhwZPwoffUDZ6tbS/IjaMAIPaL5Vh6B1oyN8M0qYtQ8 98 L6IVTN8f3MnTrqHulGWfx6PnSOjgLQ640Z/SY9KMNnZvs66Ag7ka+2v7BDPYv3Ik 99 eUyPPQbrxDYs37vfa+iFKU/5CgYKQFbFmeiP6C/jaExSz+up+ImwUyaVJWZjTWlh 100 9z4dp7Z3C+avY4HzOEu/DlaPDAOSKnlHRRaeX3Fyv41cva0CHxaJsbdeF/UrkTef 101 ClhOxvl+ZEFGqgbBvU/5nAUKk/1Ai/iPQ7Rfw/lKMc0/aLE3wx4WVxy2cVPlmxmQ 102 2u3RwwRFAgMBAAECggEAb7XmV2FAkTeZ/+x3DTCwW6d/0PKr+dkavwqrdNTlNlR5 103 SIXgjuRRl2Ti2iQFsJz5ifBFLjqMVWDVP/jMU9FWaoOpZPfEzw2NCUP/6wCfxbR0 104 Ydow+bpbvta8/gfTbI1sQR/PY/ur61WjlEFryaitPtj0S8Wz+nuRd3sdr31AotzD 105 HV/oxjZffZrVkq3gKvu9v9KX96ExXitZQ4zk9bh5As8pwbdOcOni6kFjr3OXZ0nC 106 agPsLwGvL+t+Nq6md/MwvU8t0GdCoBX4IuS/gC9BAuCE0S1F5nJUZ2W4iqsCUbQA 107 /BCIkRv30DSgHgLSxKp6KZt+VVgNIlV5URrJ1A+h3QKBgQDbXkMNdSfowI6UusMr 108 xoG8J1KoHFp2QhT5gyMNK/sNYPHpMvQJQWSaEaqzGaeNAvuzfAoDbEs2S5i0BhU0 109 UzNpZ/PkREBaBaIk0lNMoiVv7yk6CQIz12CVVgd7iD9xPDX6BiTrtrpNfod1zySF 110 zzqV0qJ8RD7ipB/n5/1fpuwJDwKBgQDLl3CvCPe+anXMhWFNC3PFy+h9lHA7eo4n 111 9FAwducgq1IHxy6qspf0Y7nZPv6CY3kQbTRWyaFP4M4HCPJpmYEkZWmxvzcjDI2L 112 1kTSHkNgr8EXP/w+6tMO0zkU3MtvqhX2CybLuY9u7O2Cnmvze9PAE2fDV0YjLngK 113 0Lr8N9MVawKBgCPiwrNT5Ah2X5zDBKSHn7eI80OfB8lqvAWpRzWjaTliD5DnjfZp 114 pSxzEWqlGry9rTFKbFTtBUzHhx6EFDnwFmv63nIMHD7dxw2g/pF9wQQTqrncuWiD 115 pkAnx6eUvVQn1milUqrgxI9i0IQcM8xT/zB9Oal8fJEU6kdEszVPmDNPAoGBAL4d 116 kfVxq1+eLJiq6Py4OAk568XxKojwXfVDeOp47kYclYJ75sEx+yIVSkRrReFeoHvN 117 bnWo3cEozVvWaABify0MopGAXS2WmEs/8I5CAms0VFywvI3IXQTYC9LGiBajPtS+ 118 /yB5DE7qYrR52ZbKSCdyN5A7XFyYFTMMTcAfJTc3AoGADyQ5MTQVcQHKtTULy5/6 119 RCqu3NBv4fj237N7FPiBJv/aAhz/nNSi98CPUESJ++5KtIrbLmm02Gm2Bi+WGU92 120 gn3QD885jR7bH2kvUg1NSrjoAYqb3AwnGduILus/MbsoizSIgEJZeTUQFJ/sr5Q1 121 k4M8rcOBNRgCFpwDm9DC+fI= 122 -----END PRIVATE KEY-----`) 123 rsaCertPEM = []byte(`-----BEGIN CERTIFICATE----- 124 MIIDazCCAlOgAwIBAgIUWKKpMWB8DhGCOtOKV41eBwhLo60wDQYJKoZIhvcNAQEL 125 BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM 126 GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yMjA4MjIxOTAxMDFaFw0yMjA5 127 MjExOTAxMDFaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw 128 HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggEiMA0GCSqGSIb3DQEB 129 AQUAA4IBDwAwggEKAoIBAQCudYRUc0u2xdQiwzEckPP9lVnXmC2b8vkstKhwZPwo 130 ffUDZ6tbS/IjaMAIPaL5Vh6B1oyN8M0qYtQ8L6IVTN8f3MnTrqHulGWfx6PnSOjg 131 LQ640Z/SY9KMNnZvs66Ag7ka+2v7BDPYv3IkeUyPPQbrxDYs37vfa+iFKU/5CgYK 132 QFbFmeiP6C/jaExSz+up+ImwUyaVJWZjTWlh9z4dp7Z3C+avY4HzOEu/DlaPDAOS 133 KnlHRRaeX3Fyv41cva0CHxaJsbdeF/UrkTefClhOxvl+ZEFGqgbBvU/5nAUKk/1A 134 i/iPQ7Rfw/lKMc0/aLE3wx4WVxy2cVPlmxmQ2u3RwwRFAgMBAAGjUzBRMB0GA1Ud 135 DgQWBBTqyM9oMkpwxREibsYlOhq3gs+3yTAfBgNVHSMEGDAWgBTqyM9oMkpwxREi 136 bsYlOhq3gs+3yTAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCf 137 mdUw76V5pyMt+2wIurGDdItl6OZDmNOh7HGR6Nh7Y9pRe1cjzdRweIbH5CA+NLuv 138 J1rQB1pdt1Jk6fnH2hk8U8rpGFoZgHFHEVaIo5sge4HCL2qlnBPU5skDH7D891HK 139 qEzAKNJRsJTqzmItzBDQzjZ185BijcM/X3NZjTfiOGJwcMehH/F85syXQLODrXgp 140 mg0exCUFW40aXpfm0z0dNNwoN+FPSefKMYMQ1LV87I6zGnmVTYH9Nix3REiuliIQ 141 7XXnJc7A6tsc6yXdVG6IpGnKXuTvl/r4iIbH+JDv3MDSvZSCE5kzAPFjgB3zMAZ8 142 Z0+424ERgom0Zdy75Y8I 143 -----END CERTIFICATE-----`) 144 )