1 // Copyright 2012 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 // Tests for CertificateUtil. 16 17 #include <polo/util/certificateutil.h> 18 #include <gtest/gtest.h> 19 #include <gmock/gmock.h> 20 #include <openssl/err.h> 21 22 namespace polo { 23 namespace util { 24 25 // Tests reading an X509 certificate from a PEM encoded string. 26 TEST(CertificateUtilTest, X509FromPEM) { 27 std::string pem = "-----BEGIN CERTIFICATE-----\n" 28 "MIICAzCCAWwCCQD5/Q86s0olWDANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJB\n" 29 "VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0\n" 30 "cyBQdHkgTHRkMCAXDTExMDExOTE3MjUzMFoYDzIyODQxMTAyMTcyNTMwWjBFMQsw\n" 31 "CQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJu\n" 32 "ZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCg\n" 33 "/IcUHnAdzIChv9kQzX07F6t4LtEwPbu3vLagYjh4pzCNFQe3Wz51ce7mknqbDlKT\n" 34 "7iTvwLPw6WBZe72VDpIRRX4+3tT9drMBpdB52Ix3sOu1HxwusAUUvOzXXHiQYGQt\n" 35 "CZUfYBX/siwBZ4/llK5C/035NGG9OkvQ1J8BPKyWoQIDAQABMA0GCSqGSIb3DQEB\n" 36 "BQUAA4GBAJMEBv/UT1Qnkp+xIrlPGkiXOOz1I0ydSz1DKBzGfmDGZ4a3+uFGAh8P\n" 37 "XO45IugMw/natOEXfhe9s0ZKHhszQg3bVU3+15/uw/XIN31EzyZwkOGvQfrCLcDi\n" 38 "N9HU05VV+pQLN916Fo7EEmCx0cu/c82qhrACYQMsBWXPyLiJh0Lq\n" 39 "-----END CERTIFICATE-----\n"; 40 41 X509* x509 = CertificateUtil::X509FromPEM(pem); 42 43 if (!x509) { 44 std::cerr << ERR_error_string(ERR_get_error(), NULL); 45 } 46 47 ASSERT_TRUE(x509); 48 X509_free(x509); 49 } 50 51 // Tests converting an X509 certificate to a PEM encoded string. 52 TEST(CertificateUtilTest, X509ToPEM) { 53 X509* x509 = X509_new(); 54 EVP_PKEY* pkey = EVP_PKEY_new(); 55 56 std::string rsa_string = "-----BEGIN RSA PRIVATE KEY-----\n" 57 "MIICXAIBAAKBgQDP5u0Bvw3N2H2g3kZB4snFiaylHh7JsF2HAdG1zIkNSyQ7jtrZ\n" 58 "b31R8GC/sqrtpGuyysQBb6DJKc9+YCH348PS52moieCUaIz48xJyx2UyfUgns1YH\n" 59 "D+lcLG1NozBTKj75z0+s2InvCNM5WaZ2RzZf8wme2AZFKQ310AGrCLMmyQIDAQAB\n" 60 "AoGAKpJy/eSNgxVNxF8/q8Yw4w5qF/WvAEXpIPgyZTPY7KvyY2/BSL0XwGukpByF\n" 61 "+9urYhU7RcACAK9bGdm9mvE869hLpDVcsPAza8DjGQFpJk/NLSzoP71fKtxxtRZW\n" 62 "VmehimP8BYMUWLG0wXaH+80wEo8Ux9vGZDBA8qIALdzcUnECQQD5NVFyn0FogoBt\n" 63 "MtPftNNSYEGgUVIOIN5VS1i39p3Bo8NAlkw2iL0u1yT5eVGOCyTRLcILj0ALht45\n" 64 "Gz9KY5y/AkEA1ZFr5xcVjvOUmNGe+L1sztEQsED5ksgbCLgrjTrWys+E5IUoL1xO\n" 65 "WZ0Y0J7xzmJAQsIrE3YHWqAkH5VP8us2dwJAV6oH4rhe+/KcVs2AdrtXcyzlKQ4y\n" 66 "PUIWtA5zQROB3zJKZxf3618ina2VFiU1KTCGXQcpsYNM1kE1PwV0uCheZQJAFOD1\n" 67 "oo7wLZyEj3gWyYyDQajQr9p6S65CblTK9TCmZQdqn4ihCBhHFJ22GlcfnqSeUah3\n" 68 "25wzVdnIDkpjmYUDOwJBAKKqyoUlxeuofTQ+IfqQXnrqmwV8plYOPrXS36RrU84L\n" 69 "VNB7JoD+vW2xKBXx2BxIbJ4dM7KrqaOP3j0tKoIX4Xc=\n" 70 "-----END RSA PRIVATE KEY-----\n"; 71 72 BIO* rsa_bio = BIO_new_mem_buf(&rsa_string[0], rsa_string.size()); 73 RSA* rsa = PEM_read_bio_RSAPrivateKey(rsa_bio, NULL, NULL, NULL); 74 BIO_free(rsa_bio); 75 76 EVP_PKEY_assign_RSA(pkey, rsa); 77 78 X509_set_version(x509, 2); 79 ASN1_INTEGER_set(X509_get_serialNumber(x509), 0); 80 ASN1_TIME_set(X509_get_notBefore(x509), 0); 81 ASN1_TIME_set(X509_get_notAfter(x509), 60*60*24*365); 82 X509_set_pubkey(x509, pkey); 83 X509_NAME* name = X509_get_subject_name(x509); 84 X509_NAME_add_entry_by_NID(name, 85 NID_commonName, 86 MBSTRING_ASC, 87 (unsigned char*) "testing", 88 -1, 89 -1, 90 0); 91 X509_set_issuer_name(x509, name); 92 X509_sign(x509, pkey, EVP_sha256()); 93 94 std::string pem = CertificateUtil::X509ToPEM(x509); 95 96 X509_free(x509); 97 EVP_PKEY_free(pkey); 98 99 std::string expected = "-----BEGIN CERTIFICATE-----\n" 100 "MIIBmDCCAQGgAwIBAgIBADANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDEwd0ZXN0\n" 101 "aW5nMB4XDTcwMDEwMTAwMDAwMFoXDTcxMDEwMTAwMDAwMFowEjEQMA4GA1UEAxMH\n" 102 "dGVzdGluZzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAz+btAb8Nzdh9oN5G\n" 103 "QeLJxYmspR4eybBdhwHRtcyJDUskO47a2W99UfBgv7Kq7aRrssrEAW+gySnPfmAh\n" 104 "9+PD0udpqInglGiM+PMScsdlMn1IJ7NWBw/pXCxtTaMwUyo++c9PrNiJ7wjTOVmm\n" 105 "dkc2X/MJntgGRSkN9dABqwizJskCAwEAATANBgkqhkiG9w0BAQsFAAOBgQC+Ibl9\n" 106 "EPNGkZRR4oGt0WIOpJSRzJMvH/EvS6i5COAS0st7FXpxkuiCTpBCAabBmf4D6Lvt\n" 107 "pRS73QFpXgH6ZhSHb/K1Xs8tzJ7QlnxE+iGm0r+w/3/wKANwy9s+S1KFgkJwZ10z\n" 108 "qyJ0wjxMi/8exSg3PGs71P1L/pkzI24VN/+mPA==\n" 109 "-----END CERTIFICATE-----\n"; 110 111 ASSERT_EQ(expected, pem); 112 } 113 114 // Tests reading a private key from a PEM encoded string. 115 TEST(CertificateUtilTest, PKEYFromPEM) { 116 std::string pem = "-----BEGIN RSA PRIVATE KEY-----\n" 117 "Proc-Type: 4,ENCRYPTED\n" 118 "DEK-Info: DES-EDE3-CBC,5351BC9DC2349695\n" 119 "\n" 120 "Dmr011r9Nn86mHljRTE59DThzsQaYAnJPUvboEY/jriqc8n/kE0IvtaM/Stutlzp\n" 121 "jMbL/1ddjIeyStWM17DTlEeu1DFCoLnmVqwn1p2x2Y5gW72CYx5oawDj7rg8Jczj\n" 122 "mUfuRBU69pa17dT/3qjiNwEWz90NoNwxcMe7lP2uULyB75hDNCQ9mjN1WN1iAyiS\n" 123 "zehrScLk/3Y3QD0KLk2TM8CLuWyaf1K7NhyWBWatxhWcVe2Zw48MGA1sUTnb5m67\n" 124 "yyS+/Doonqhko+a/5ycnu+MiE4V4KrGyBrkqK0KO6kWVB7bxudC/5S+x85b9VDNc\n" 125 "GPfquXpHisouUaW9EnqGnk3E/kaOUamACgZHdrXDqeBXaAulSbZ0f1I9hHP6yULg\n" 126 "IWqkeLx3f+GPYbYwdVzp7gc94xdjcsXUG3BWwuL4PD8VJXUrNJH0RJMK5SDZrNhF\n" 127 "WLizlzjwYfM0wZhcaWjBY/6tz7gkz4bSG9skl9HLvFK7bKyarRjP6P6LQJJXz3hB\n" 128 "LAj95Vye8mWfY+WHV+POB2sxQ9riXiyy5UnSnhqvAhLBWNBjSYq8WM+MtLmZf2OA\n" 129 "H6w0JPK/smd4K+xyFUNh2g2w4feS1glVl9LYzKopZNEu4Vb0jc3Akd92hMR1bSww\n" 130 "fXi8D/4XV3mHSsF91bT0Jn/1n93qtr++FpztTU4KcFB3OJur2QUoHvH7ei/NdxW5\n" 131 "yJaxcFwWhGtmx1SVGuNb3yC6rm/hKrzi5998UTPE/9gQiJgVXenR9ve2IcbIaBur\n" 132 "avtnvFQ+6xAApwgi0q6rw6I5AeF7dD226+LY9gpfu6ZzrFbOlv+7Tg==\n" 133 "-----END RSA PRIVATE KEY-----\n"; 134 135 EVP_PKEY* pkey = CertificateUtil::PKEYFromPEM(pem, "testing"); 136 137 ASSERT_TRUE(pkey); 138 139 RSA* rsa = EVP_PKEY_get1_RSA(pkey); 140 ASSERT_TRUE(rsa); 141 142 EVP_PKEY_free(pkey); 143 } 144 145 // Tests converting a private key to a PEM encoded string. 146 TEST(CertificateUtilTest, PKEYToPEM) { 147 EVP_PKEY* pkey = EVP_PKEY_new(); 148 RSA* rsa = RSA_generate_key(1025, RSA_F4, NULL, NULL); 149 EVP_PKEY_assign_RSA(pkey, rsa); 150 151 std::string pem = CertificateUtil::PKEYToPEM(pkey, "testing"); 152 153 ASSERT_TRUE(pem.size()); 154 155 // Difficult to verify the PEM because the encryption is random, so just make 156 // sure we can read it back in with the supplied passphrase. 157 EVP_PKEY* verify = CertificateUtil::PKEYFromPEM(pem, "testing"); 158 ASSERT_TRUE(verify); 159 160 EVP_PKEY_free(pkey); 161 EVP_PKEY_free(verify); 162 } 163 164 // Tests generating a new private key. 165 TEST(CertificateUtilTest, GeneratePrivateKey) { 166 EVP_PKEY* pkey = CertificateUtil::GeneratePrivateKey(); 167 ASSERT_TRUE(pkey); 168 EVP_PKEY_free(pkey); 169 } 170 171 // Tests generating a self-signed certificate. 172 TEST(CertificateUtilTest, GenerateSelfSignedCert) { 173 EVP_PKEY* pkey = CertificateUtil::GeneratePrivateKey(); 174 ASSERT_TRUE(pkey); 175 176 X509* x509 = CertificateUtil::GenerateSelfSignedCert(pkey, "test", 365); 177 ASSERT_TRUE(x509); 178 179 EVP_PKEY_free(pkey); 180 X509_free(x509); 181 } 182 183 } // namespace util 184 } // namespace polo 185