Home | History | Annotate | Download | only in fastbootd
      1 /*
      2  * Copyright (c) 2009-2013, Google Inc.
      3  * All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  *  * Redistributions of source code must retain the above copyright
      9  *    notice, this list of conditions and the following disclaimer.
     10  *  * Redistributions in binary form must reproduce the above copyright
     11  *    notice, this list of conditions and the following disclaimer in
     12  *    the documentation and/or other materials provided with the
     13  *    distribution.
     14  *  * Neither the name of Google, Inc. nor the names of its contributors
     15  *    may be used to endorse or promote products derived from this
     16  *    software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     21  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
     22  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
     23  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     24  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
     25  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
     26  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     27  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
     28  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     29  * SUCH DAMAGE.
     30  */
     31 
     32 
     33 #include <openssl/pem.h>
     34 #include <openssl/engine.h>
     35 #include <openssl/x509.h>
     36 #include <openssl/x509v3.h>
     37 #include <openssl/pem.h>
     38 #include <openssl/cms.h>
     39 #include <sys/types.h>
     40 #include <sys/stat.h>
     41 #include <unistd.h>
     42 
     43 #include "secure.h"
     44 #include "debug.h"
     45 #include "utils.h"
     46 
     47 
     48 void cert_init_crypto() {
     49     CRYPTO_malloc_init();
     50     ERR_load_crypto_strings();
     51     OpenSSL_add_all_algorithms();
     52     ENGINE_load_builtin_engines();
     53 }
     54 
     55 X509_STORE *cert_store_from_path(const char *path) {
     56 
     57     X509_STORE *store;
     58     struct stat st;
     59     X509_LOOKUP *lookup;
     60 
     61     if (stat(path, &st)) {
     62         D(ERR, "Unable to stat cert path");
     63         goto error;
     64     }
     65 
     66     if (!(store = X509_STORE_new())) {
     67         goto error;
     68     }
     69 
     70     if (S_ISDIR(st.st_mode)) {
     71         lookup = X509_STORE_add_lookup(store,X509_LOOKUP_hash_dir());
     72         if (lookup == NULL)
     73             goto error;
     74         if (!X509_LOOKUP_add_dir(lookup, path, X509_FILETYPE_PEM)) {
     75             D(ERR, "Error loading cert directory %s", path);
     76             goto error;
     77         }
     78     }
     79     else if(S_ISREG(st.st_mode)) {
     80         lookup = X509_STORE_add_lookup(store,X509_LOOKUP_file());
     81         if (lookup == NULL)
     82             goto error;
     83         if (!X509_LOOKUP_load_file(lookup, path, X509_FILETYPE_PEM)) {
     84             D(ERR, "Error loading cert directory %s", path);
     85             goto error;
     86         }
     87     }
     88     else {
     89         D(ERR, "cert path is not directory or regular file");
     90         goto error;
     91     }
     92 
     93     return store;
     94 
     95 error:
     96     return NULL;
     97 }
     98 
     99 
    100 int cert_read(int fd, CMS_ContentInfo **content, BIO **output) {
    101     BIO *input;
    102     *output = NULL;
    103 
    104 
    105     input = BIO_new_fd(fd, BIO_NOCLOSE);
    106     if (input == NULL) {
    107         D(ERR, "Unable to open input");
    108         goto error;
    109     }
    110 
    111     //TODO:
    112     // read with d2i_CMS_bio to support DER
    113     // with java or just encode data with base64
    114     *content = SMIME_read_CMS(input, output);
    115     if (*content == NULL) {
    116         unsigned long err = ERR_peek_last_error();
    117         D(ERR, "Unable to parse input file: %s", ERR_lib_error_string(err));
    118         goto error_read;
    119     }
    120 
    121     BIO_free(input);
    122 
    123     return 0;
    124 
    125 error_read:
    126     BIO_free(input);
    127 error:
    128     return 1;
    129 }
    130 
    131 int cert_verify(BIO *content, CMS_ContentInfo *content_info, X509_STORE *store, int *out_fd) {
    132     BIO *output_temp;
    133     int ret;
    134 
    135     *out_fd = create_temp_file();
    136     if (*out_fd < 0) {
    137         D(ERR, "unable to create temporary file");
    138         return -1;
    139     }
    140 
    141     output_temp = BIO_new_fd(*out_fd, BIO_NOCLOSE);
    142     if (output_temp == NULL) {
    143         D(ERR, "unable to create temporary bio");
    144         close(*out_fd);
    145         return -1;
    146     }
    147 
    148     ret = CMS_verify(content_info, NULL ,store, content, output_temp, 0);
    149 
    150     if (ret == 0) {
    151         char buf[256];
    152         unsigned long err = ERR_peek_last_error();
    153         D(ERR, "Verification failed with reason: %s, %s", ERR_lib_error_string(err),  ERR_error_string(err, buf));
    154         D(ERR, "Data used: content %p", content);
    155     }
    156 
    157     ERR_clear_error();
    158     ERR_remove_state(0);
    159 
    160     BIO_free(output_temp);
    161 
    162     return ret;
    163 }
    164 
    165 void cert_release(BIO *content, CMS_ContentInfo *info) {
    166     BIO_free(content);
    167     CMS_ContentInfo_free(info);
    168 }
    169 
    170