/*
 * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the Apache License 2.0 (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

/* Simple S/MIME decryption example */
#include <openssl/pem.h>
#include <openssl/cms.h>
#include <openssl/err.h>
#include "scep.h"

int verify(CMS_ContentInfo *pkiMessage, X509 * ca_cert, BIO **encData)
{
    int error = 0;
    BIO *data = NULL;
    X509_STORE *store = X509_STORE_new();
    
    X509_STORE_add_cert(store, ca_cert);
    data = BIO_new(BIO_s_mem());

    if (!CMS_verify(pkiMessage, NULL, store, NULL, data, CMS_NO_SIGNER_CERT_VERIFY)) {
        error = 1;
    }
    *encData = data;
    return error;
}


int main(int argc, const char * argv[]) {
    
    printf("BEGIN CMS decrypt program\n");
    
    // OpenSSL setup
    OpenSSL_add_all_algorithms();
    ERR_load_crypto_strings();
    
    // Decryption certificate and key
    BIO *rawcacert = NULL;
    BIO *rawkey = NULL;
    X509 *cacert;
    EVP_PKEY *cakey;
    
    // Input data
    BIO *in ;//= BIO_new(BIO_s_file());
    CMS_ContentInfo *pkiMessage = NULL;
    CMS_ContentInfo *p7env;
    BIO *encData;

    // Output
    BIO *decData = NULL;
    decData = BIO_new(BIO_s_mem());
    SCEP_DATA *output = NULL;
    output = malloc(sizeof(SCEP_DATA));
    
    // prepare datastructures
    encData = BIO_new(BIO_s_mem());
    decData = BIO_new(BIO_s_mem());
    
    // load cacert from disk
    rawcacert = BIO_new_file("scep.pem", "r");
    cacert = PEM_read_bio_X509(rawcacert, NULL, 0, NULL);

    // load cakey from disk
    rawkey = BIO_new_file("scep.key", "r");
    cakey = PEM_read_bio_PrivateKey(rawkey, NULL, 0, NULL);
    
    in = BIO_new_file("pkimessage.p7b", "r");
    pkiMessage = PEM_read_bio_CMS(in, NULL, NULL, NULL);
        
    if(verify(pkiMessage, cacert, &encData) == 0) {
        printf("PKCS7 verified\n");
    } else {
        printf("PKCS7 verify failed\n");
        exit(1);
    }
    
    p7env = d2i_CMS_bio(encData, NULL);
    
    if(CMS_decrypt(p7env, cakey, cacert, NULL, decData, 0)) {
        printf("PKCS7 decrypted\n");
    } else {
        printf("PKCS7 decryption failed\n");
        exit(1);
    }
    
    // Output
    output->request = NULL;
    d2i_X509_REQ_bio(decData, &(output->request));
    if(!output->request){
        printf("Not valid CSR after decrpytion");
        exit(1);
    }
    
    printf("Name: %s\n", X509_NAME_oneline(X509_REQ_get_subject_name(output->request), 0, 0));
}
