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  )