github.com/letsencrypt/trillian@v1.1.2-0.20180615153820-ae375a99d36a/crypto/keys/pem/pem_test.go (about) 1 // Copyright 2016 Google Inc. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package pem_test 16 17 import ( 18 "crypto" 19 "testing" 20 21 . "github.com/google/trillian/crypto/keys/pem" 22 ktestonly "github.com/google/trillian/crypto/keys/testonly" 23 "github.com/google/trillian/crypto/keyspb" 24 "github.com/google/trillian/testonly" 25 ) 26 27 const ( 28 _ = ` 29 -----BEGIN PUBLIC KEY----- 30 MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEvuynpVdR+5xSNaVBb//1fqO6Nb/nC+WvRQ4bALzy4G+QbByvO1Qpm2eUzTdDUnsLN5hp3pIXYAmtjvjY1fFZEg== 31 -----END PUBLIC KEY-----` 32 ecdsaPrivateKey = ` 33 -----BEGIN PRIVATE KEY----- 34 MHcCAQEEIHG5m/q2sUSa4P8pRZgYt3K0ESFSKp1qp15VjJhpLle4oAoGCCqGSM49AwEHoUQDQgAEvuynpVdR+5xSNaVBb//1fqO6Nb/nC+WvRQ4bALzy4G+QbByvO1Qpm2eUzTdDUnsLN5hp3pIXYAmtjvjY1fFZEg== 35 -----END PRIVATE KEY----- 36 ` 37 _ = ` 38 -----BEGIN PUBLIC KEY----- 39 MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsMB4reLZhs+2ReYX01nZpqLBQ9uhcZvBmzH54RsZDTb5khw+luSXKbLKXxdbQfrsxURbeVdugDNnV897VI43znuiKJ19Y/XS3N5Z7Q97/GOxOxGFObP0DovCAPblxAMaQBb+U9jkVt/4bHcNIOTZl/lXgX+yp58lH5uPfDwav/hVNg7QkAW3BxQZ5wiLTTZUILoTMjax4R24pULlg/Wt/rT4bDj8rxUgYR60MuO93jdBtNGwmzdCYyk4cEmrPEgCueRC6jFafUzlLjvuX89ES9n98LxX+gBANA7RpVPkJd0kfWFHO1JRUEJr++WjU3x4la2Xs4tUNX4QBSJP4XEOXwIDAQAB 40 -----END PUBLIC KEY-----` 41 rsaPrivateKey = ` 42 -----BEGIN PRIVATE KEY----- 43 MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCwwHit4tmGz7ZF5hfTWdmmosFD26Fxm8GbMfnhGxkNNvmSHD6W5JcpsspfF1tB+uzFRFt5V26AM2dXz3tUjjfOe6IonX1j9dLc3lntD3v8Y7E7EYU5s/QOi8IA9uXEAxpAFv5T2ORW3/hsdw0g5NmX+VeBf7KnnyUfm498PBq/+FU2DtCQBbcHFBnnCItNNlQguhMyNrHhHbilQuWD9a3+tPhsOPyvFSBhHrQy473eN0G00bCbN0JjKThwSas8SAK55ELqMVp9TOUuO+5fz0RL2f3wvFf6AEA0DtGlU+Ql3SR9YUc7UlFQQmv75aNTfHiVrZezi1Q1fhAFIk/hcQ5fAgMBAAECggEAcpuq5J2GjQqcVwCWjF3jalB4XsbIDUGArWAfdd47RT1TYHFeCDua5Nfgrv4XF1ZcNqFXavvNU+WA6ghIIRDCkOnLwOg1yR45pyuqRbPXolUGM5Xtu/e6lb/7gOKXI50bZVlDehzWGprJm5MqeRzLFub/3aFut4/S44bb6COU+Mo6bsm+/2hcuOtUeDR5fOc49tTAZZSG6kVAXdWG5raU4a/Qx6LCR5zMjhzqy8FMGkW+eww243WM/5RCW6pzgwjFVPyfrg/Jqc2IgAPuFEStvK6jAsPaZxb7t1ue79ku8+xLDpJSgLUF3jU9Qy8+VphnmbHrYSqDSNUyfj8+qcbI0QKBgQDc/GD7Yprw4zp3IqLoYd96dqJtlloUgd7kGebDfAftAgo2ooS8tpbAYGvgmeMDqAfqfTkOJUACCHptnpUWusXJqW6SW9bk17jGb/pPcQiXmaNPGYbpPlamueUmS9gdatvw6iXewRqjltNMng+mfbvAmaFe+qeqCq86R9BoUFVBCQKBgQDMwd+6DKGKH/hgChweUtNLMmeOmzYskcUL43cLeAAwwlL4DruLthBb/0SYeMQ+sXpYDL3b1/i03Ln5P5g8KFL8EgIayInlZJHiHjOn9LF+S5gv5snI0Fdk2O8eNHCSiS0+qqPU8ZKTKwnbt8M+OqLhJD0C7N35oYAoCj0uhSp2JwKBgQDBIxqn2tBMBGyOvwjeTNwCrjjbynJERhVGCpUy+O38aLIAeh3EyVgMHrlp/VT5VxxEBtmc0VWV8U7/C4CF8wr2a0ymQfoY26k0VZ3RXJsD1FV0xnyw0bjt0r7Br7vcSg6cCii6/M6Jd0KJTgOjoXQ8qojs9+kdpmTrbORqpvs78QKBgQC13ZW8CLAKoS7ZDuG+xU5LQi/c6FuL5sWgM59vHlz88f0DuwI1q7aIIAlrbAjSroy+XELeW8vZyRueGTA8boyWu+AGrgxdJaC1uKGlEp/8T2STV2fu565YMp7gsy8x2InJWYM/BnpsIRQWhffy893sH2XZjU30BdBwv/drtHfsjQKBgHQgInEA+pwo/laVgVkuIlL/0avlRRG06TsMUJYDP9jOfzdoWZrsCVr4uLXMR1zJ2I/tmKv+u+35luu2rVnItB7hSJgMy+6Bxj4DL5QE9BuLVARDMGrj05oZXPw9954HjN87b4dVvSKl2hPz6lcsKDlPJy+OvXdsZxfc9NaCCQNT 44 -----END PRIVATE KEY----- 45 ` 46 _ = ` 47 -----BEGIN PUBLIC KEY----- 48 MIIDRjCCAjkGByqGSM44BAEwggIsAoIBAQDgLI6pXvqpcOY33lzeZrjUBHxphiz0I9VKF9vGpWymNfBptQ75bpQFe16jBjaOGwDImASHTp53XskQJLOXC4bZxoRUHsm8bHQVZHQhYgxn8ZDQX/40zOR1d73y1TXSiULo6rDKVlM+fFcm33tGv+ZOdfaIhW17c5jvDAy6UWqQakasvL+kfiejIDGHjLVFWwX0vLCG+pAomgO6snQHGcPhDO9uxEYPd9on7YTgBrpa2IcXk5jFeY8xOxMnMwoBojRvH97+ivdBR1yW8f+4FAGg5o1eFV5ZqoUAF8GO3BBEwluMGNeT7gMgl4PO8N8xBxJulHd3tLW5qkW0cBPwkbzzAiEAvdYeMPamsFAyd7s07dt78wxXyHGrwVl2AcQBo0QTATkCggEASH9Rp+EjNkL7uCqGJ78P4tjJM+2+xaEhZpJ/kTzq6DtdFhu5Rov6lN5NnZKPSUNYr9Vkmu88ru0iND1N37z0rJpImksXKxCv0AwBkwtqCwf9jjkTrZiGRzP8xf789wK+uG7Uud20ml9QzXKr9Af9WrRx3DtCq44PBaIlhPvpZS9znCZsuUZqYZFW3/oD4EhwPgVLSWeulh1t33ku3mYQwVS8ZTdJGPyFRoD1dcQ4EchR4ce0u0nTXlqErWhfnmb9msF6dFCV0Mx5yrqxkEHbJ/vZgB4zAdOke7XiJsWqIok/7IJpJuVOvkY9NHgBdlq3xU180+pEo2NrGm4pbrGm1wOCAQUAAoIBAAGbucHEfgtcu++OQQjYqneukv4zqcP/PCJTP+GuXen6SH25V2ZlHC88lG6qdZVBPWZidAb9BSoUQpW7BzauKRqH7rKOsIeqvEPCiWBKA781Zi5HAWGhC4INJJx54Q66F54DkGlTRVFkXlGpAIudhfAIG//MyO9TIsLSgRyqjKWVm+/XhWDIT5iMJZZ/IgmbICueaa7go8poHuTTyUDPHPIeL5d9Aru7qD4JtX+UVy6GYKhWx/guv+A7zyJ8d1kMLsmUAro80DLPDoais2I8YPpbu+xTSLLswIYddDdwg3P8mMAGzuWY/ZLumwpRr/fbI+t2Sm9KKGNGkGGIKAg43cs= 49 -----END PUBLIC KEY-----` 50 corruptEcdsaPrivateKey = ` 51 -----BEGIN PRIVATE KEY----- 52 NHcCAQEEIHG5m/q2sUSa4P8pRZgYt3K0ESFSKp1qp15VjJhpLle4oAoGCCqGSM49AwEHoUQDQgAEvuynpVdR+5xSNaVBb//1fqO6Nb/nC+WvRQ4bALzy4G+QbByvO1Qpm2eUzTdDUnsLN5hp3pIXYAmtjvjY1fFZEg== 53 -----END PRIVATE KEY----- 54 ` 55 ) 56 57 func TestFromProto(t *testing.T) { 58 for _, test := range []struct { 59 desc string 60 keyProto *keyspb.PEMKeyFile 61 wantErr bool 62 }{ 63 { 64 desc: "PEMKeyFile", 65 keyProto: &keyspb.PEMKeyFile{ 66 Path: "../../../testdata/log-rpc-server.privkey.pem", 67 Password: "towel", 68 }, 69 }, 70 { 71 desc: "PemKeyFile with non-existent file", 72 keyProto: &keyspb.PEMKeyFile{ 73 Path: "non-existent.pem", 74 }, 75 wantErr: true, 76 }, 77 { 78 desc: "PemKeyFile with wrong password", 79 keyProto: &keyspb.PEMKeyFile{ 80 Path: "../../../testdata/log-rpc-server.privkey.pem", 81 Password: "wrong-password", 82 }, 83 wantErr: true, 84 }, 85 { 86 desc: "PemKeyFile with missing password", 87 keyProto: &keyspb.PEMKeyFile{ 88 Path: "../../../testdata/log-rpc-server.privkey.pem", 89 }, 90 wantErr: true, 91 }, 92 } { 93 signer, err := FromProto(test.keyProto) 94 if gotErr := err != nil; gotErr != test.wantErr { 95 t.Errorf("%v: FromProto(%#v) = (_, %q), want (_, nil)", test.desc, test.keyProto, err) 96 continue 97 } else if gotErr { 98 continue 99 } 100 101 // Check that the returned signer can produce signatures successfully. 102 if err := ktestonly.SignAndVerify(signer, signer.Public()); err != nil { 103 t.Errorf("%v: SignAndVerify() = %q, want nil", test.desc, err) 104 } 105 } 106 } 107 108 func TestLoadPrivateKeyAndSign(t *testing.T) { 109 tests := []struct { 110 desc string 111 keyPEM string 112 keyPath string 113 keyPass string 114 wantLoadErr bool 115 }{ 116 { 117 desc: "ECDSA with password", 118 keyPEM: testonly.DemoPrivateKey, 119 keyPass: testonly.DemoPrivateKeyPass, 120 }, 121 { 122 desc: "ECDSA from file with password", 123 keyPath: "../../../testdata/log-rpc-server.privkey.pem", 124 keyPass: "towel", 125 }, 126 { 127 desc: "Non-existent file", 128 keyPath: "non-existent.pem", 129 wantLoadErr: true, 130 }, 131 { 132 desc: "ECDSA with wrong password", 133 keyPEM: testonly.DemoPrivateKey, 134 keyPass: testonly.DemoPrivateKeyPass + "foo", 135 wantLoadErr: true, 136 }, 137 { 138 desc: "ECDSA", 139 keyPEM: ecdsaPrivateKey, 140 }, 141 { 142 desc: "RSA", 143 keyPEM: rsaPrivateKey, 144 }, 145 { 146 desc: "ECDSA with leading junk", 147 keyPEM: "foobar\n" + ecdsaPrivateKey, 148 }, 149 { 150 desc: "ECDSA with trailing junk", 151 keyPEM: ecdsaPrivateKey + "\nfoobar", 152 wantLoadErr: true, 153 }, 154 { 155 desc: "Corrupt ECDSA", 156 keyPEM: corruptEcdsaPrivateKey, 157 wantLoadErr: true, 158 }, 159 } 160 161 for _, test := range tests { 162 var k crypto.Signer 163 var err error 164 switch { 165 case test.keyPEM != "": 166 k, err = UnmarshalPrivateKey(test.keyPEM, test.keyPass) 167 switch gotErr := err != nil; { 168 case gotErr != test.wantLoadErr: 169 t.Errorf("%v: UnmarshalPrivateKey() = (%v, %v), want err? %v", test.desc, k, err, test.wantLoadErr) 170 continue 171 case gotErr: 172 continue 173 } 174 175 case test.keyPath != "": 176 k, err = ReadPrivateKeyFile(test.keyPath, test.keyPass) 177 switch gotErr := err != nil; { 178 case gotErr != test.wantLoadErr: 179 t.Errorf("%v: ReadPrivateKeyFile() = (%v, %v), want err? %v", test.desc, k, err, test.wantLoadErr) 180 continue 181 case gotErr: 182 continue 183 } 184 185 default: 186 t.Errorf("%v: No PEM or file path set in test definition", test.desc) 187 continue 188 } 189 190 // Check the key by creating a signature and verifying it. 191 if err := ktestonly.SignAndVerify(k, k.Public()); err != nil { 192 t.Errorf("%v: SignAndVerify() = %q, want nil", test.desc, err) 193 } 194 } 195 }