Home | History | Annotate | Download | only in util
      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