/* Copyright 2013 Justin Erenkrantz and Greg Stein
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifdef SERF_HAVE_MACOSXSSL

#include <stdlib.h>

#include "serf.h"
#include "serf_private.h"
#include "serf_bucket_util.h"
#include "bucket_private.h"

#include <apr_strings.h>
#include <apr_sha1.h>

#include <Security/SecCertificate.h>
#include <Security/SecCertificateOIDs.h>

#define ST_DEBUG 0

/* This code reads all items DER-encoded certificate in X.509 format, as
   provided by the Keychain services API. */

/* Read ASN.1 data type OID from a DER encoded buffer. */
static const char *
read_DER_OID(const unsigned char* ptr, int clen, apr_pool_t *pool)
{
    unsigned char b;
    char *value;

    /* First two components of the OID are encoded in the first byte. */
    b = *ptr++;
    clen--;

    value = apr_psprintf(pool, "%d.%d", b/40, b%40);


    /* one or two bytes per component */
    while (clen > 0) {
        b = *ptr++;
        clen--;

        if (! (b & 0x80)) {
            value = apr_psprintf(pool, "%s.%d", value, b);
        } else {
            unsigned comp = 0;

            while (b & 0x80 && clen > 0) {
                comp <<= 7;
                comp |= (b & 0x7f);
                b = *ptr++;
                clen--;
            }
            comp <<= 7;
            comp |= (b & 0x7f);

            value = apr_psprintf(pool, "%s.%d", value, comp);
        }
    }

    serf__log(ST_DEBUG, __FILE__, "OID of length %d, value: %s .\n",
              clen, value);

    return value;
}

/* Read ASN.1 data type PrintableString from a DER encoded buffer.
   TODO: currently also used for UTF8String, use specific function for those. */
static const char *
read_DER_string(const unsigned char* ptr, int clen, apr_pool_t *pool)
{
    const char *value = apr_pstrndup(pool, (const char*)ptr, clen);

    serf__log(ST_DEBUG, __FILE__, "string of length %d, value: %s.\n",
              clen, value);

    return value;
}

/* Read ASN.1 data type BOOLEAN from a DER encoded buffer. */
static const char *
read_DER_boolean(const unsigned char* ptr, int clen, apr_pool_t *pool)
{
    unsigned char v = *ptr++;

    serf__log(ST_DEBUG, __FILE__, "Boolean of length %d, value: %s.\n",
              clen, v ? "TRUE" : "FALSE");

    return v ? "TRUE" : "FALSE";
}

/* Read ASN.1 data type BIT STRING from a DER encoded buffer. */
static const char *
read_DER_bitstring(const unsigned char* ptr, int clen, apr_pool_t *pool)
{
    char *value = "";

    /* TODO: take into account unused_bits. */
    /*    unsigned char unused_bits = *ptr++; */
    ptr++;
    clen--;

    while (clen-- > 0) {
        unsigned char b = *ptr++;
        value = apr_psprintf(pool, "%s %2x", value, b);
    }

    serf__log(ST_DEBUG, __FILE__, "Bitstring of length %d, value: %s.\n",
              clen, value);

    return value;
}

/* Read ASN.1 data type INTEGER from a DER encoded buffer. */
static const char *
read_DER_integer(const unsigned char* ptr, int clen, apr_pool_t *pool)
{
    unsigned char lb = *ptr++;
    int positive = 0;
    int i;
    unsigned long value = 0;

    if (lb == 0x00) {
        positive = 1;
        clen -= positive;


        if (clen <= sizeof(long))
            for (i = 0; i < clen; i++)
                value = (value << 8) + *ptr++;
    } else if (! (lb & 0x80)) {
        positive = 1;
        value = lb;
    } else {
        /* negative number */
        return apr_psprintf(pool, "Negative integer not supported.");
    }

    serf__log(ST_DEBUG, __FILE__, "%s integer of length %d, value: %lx.\n",
              positive ? "Positive" : "Negative", clen, value);

    return apr_psprintf(pool, "%lx", value);
}

/* Read DER Tag and Length from a DER encoded buffer. */
static apr_status_t
read_DER_TL(const unsigned char* ptr, unsigned char *tag,
            long *value_len, long *consumed)
{
    int constr_enc;
    char lb1;
    long clen = 0;

    /* read tag */
    *tag = *ptr++;
    constr_enc = *tag & 0x20;
    *consumed = 1;

    /* read length */
    lb1 = *ptr++;
    if (! (lb1 & 0x80)) {
        clen = lb1;
        (*consumed)++;
    } else {
        int i;
        lb1 &= 0x7f;
        if (lb1 > sizeof(long))
            return APR_ENOTIMPL;
        for (i = 0; i < lb1; i++)
            clen = (clen << 8) + *ptr++;
        *consumed += (lb1 + 1);
    }

    *value_len = clen;

    serf__log(ST_DEBUG, __FILE__,
              "tag: %x, value length: %d, header length: %d.\n",
              *tag, *value_len, *consumed);

    return APR_SUCCESS;
}

/* Read DER Tag, Length and primitive Value from a DER encoded buffer.
   Don't use this for constructed types SEQUENCE or SET! */
static apr_status_t
read_DER_TLvalue(const unsigned char *ptr, unsigned char *tag, long *consumed,
                 const char **value, apr_pool_t *pool)
{
    long tl_len, value_len;

    read_DER_TL(ptr, tag, &value_len, &tl_len);
    ptr += tl_len;

    switch (*tag) {
        case 0x01:
            *value = read_DER_boolean(ptr, value_len, pool);
            break;
        case 0x02:
            *value = read_DER_integer(ptr, value_len, pool);
            break;
        case 0x03:
            *value = read_DER_bitstring(ptr, value_len, pool);
            break;
        case 0x05:
            *value = "";
            serf__log(ST_DEBUG, __FILE__, "NULL value.\n");
            break;
        case 0x06:
            *value = read_DER_OID(ptr, value_len, pool);
            break;
        case 0x17: /* Date */
        case 0x16: /* IA5String */
        case 0x13: /* PrintableString */
        case 0x14: /* TeletexString */
        case 0x0c: /* UTF8String */
            *value = read_DER_string(ptr, value_len, pool);
            break;

        case 0xa0: /* Explicit tag 0, in X509 used for version. */
        default:
        {
            *value = "ERROR";
            serf__log(ST_DEBUG, __FILE__, "UNSUPPORTED TAG TYPE %2x.\n", *tag);
            return APR_ENOTIMPL;
            break;
        }
    }

    *consumed = tl_len + value_len;

    return APR_SUCCESS;
}

/* Recursively skip an entire Tag-Length-Value block. */
static apr_status_t
skip_DER_TLV(const unsigned char *ptr, unsigned char *tag, long *consumed)
{
    long tl_len, value_len;
    apr_status_t status;

    status = read_DER_TL(ptr, tag, &value_len, &tl_len);
    if (status)
        return status;

    *consumed = tl_len + value_len;

    return APR_SUCCESS;
}

#define SERF_ERR(x) status = (x);\
                    if (status) goto cleanup;

/* Reads an issuer or subject structure from PTR, which should point to the
   value of tag type 0x30 grouping either issuer or subject.
   Caller should clean up out_der. */
static apr_status_t
read_X509_DER_DistinguishedName(apr_hash_t **o, CFDataRef *out_der,
                                const unsigned char *ptr,
                                long *total_len, apr_pool_t *pool)
{
    unsigned char tag;
    long len, object_len, consumed;
    apr_status_t status;
    apr_hash_t *tgt;
    char *tmp;

    tgt = apr_hash_make(pool);

    /* RelativeDistinguishedName Sequence. */
    SERF_ERR(read_DER_TL(ptr, &tag, &object_len, &consumed));

    /* Copy this whole structure in out_der. */
    tmp = apr_palloc(pool, object_len);
    memcpy(tmp, ptr, object_len);
    *out_der = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault,
                                           (unsigned char *)tmp,
                                           object_len,
                                           kCFAllocatorNull);

    ptr += consumed;

    *total_len = object_len + consumed;
    /* For each component */
    while (object_len > 0) {
        const char *key, *value;
        long consumed;
        CFStringRef keyref;

        /* RelativeDistinguishedName Set. */
        SERF_ERR(read_DER_TL(ptr, &tag, &len, &consumed));
        ptr += consumed; object_len -= consumed;

        /* AttributeTypeAndValue, containing OID-value pair. */
        SERF_ERR(read_DER_TL(ptr, &tag, &len, &consumed));
        ptr += consumed; object_len -= consumed;

        /* Read key OID */
        SERF_ERR(read_DER_TLvalue(ptr, &tag, &consumed, &key, pool));
        ptr += consumed; object_len -= consumed;

        /* OID constants are CFStringRef, so need to use CFStringCompare. */
        keyref = CFStringCreateWithBytesNoCopy(kCFAllocatorDefault,
                                               (unsigned char *)key,
                                               strlen(key),
                                               kCFStringEncodingMacRoman,
                                               false,
                                               kCFAllocatorNull);
        
        if (CFStringCompare(keyref,
                kSecOIDOrganizationalUnitName, 0) == kCFCompareEqualTo)
            key = "OU";
        else if (CFStringCompare(keyref,
                kSecOIDOrganizationName, 0) == kCFCompareEqualTo)
            key = "O";
        else if (CFStringCompare(keyref,
                kSecOIDLocalityName, 0) == kCFCompareEqualTo)
            key = "L";
        else if (CFStringCompare(keyref,
                kSecOIDStateProvinceName, 0) == kCFCompareEqualTo)
            key = "ST";
        else if (CFStringCompare(keyref,
                kSecOIDCountryName, 0) == kCFCompareEqualTo)
            key = "C";
        else if (CFStringCompare(keyref,
                kSecOIDEmailAddress, 0) == kCFCompareEqualTo)
            key = "E";
        else if (CFStringCompare(keyref,
                kSecOIDCommonName, 0) == kCFCompareEqualTo)
            key = "CN";

        CFRelease(keyref);

        /* Read value */
        SERF_ERR(read_DER_TLvalue(ptr, &tag, &consumed, &value, pool));
        ptr += consumed; object_len -= consumed;

        serf__log(ST_DEBUG, __FILE__, "Remaining: %d.\n", object_len);

        apr_hash_set(tgt, key, APR_HASH_KEY_STRING, value);
    }

    *o = tgt;
    return APR_SUCCESS;

cleanup:
    return status;
}

/* Reads date/time string formatted as "YYMMDDHHmmSSZ" and converts it to
   "MMM dd HH:mm:ss yyyy GMT". Allocate output string from pool.
   Example: in: 130821204210Z out:Aug 13 20:42:10 2013 GMT . */
static const char *
convert_cert_date(const char *in, apr_pool_t *pool)
{
    apr_size_t len;
    apr_time_exp_t te;
    const int bufsize = 64;
    char *datestr;

    memset(&te, 0, sizeof(te));

    datestr = apr_palloc(pool, bufsize);

    /* Read 2000+yy into 1900+100+yy */
    te.tm_year = 100 + (*in -'0') * 10 + *(in+1) - '0'; in+=2;
    te.tm_mon  = (*in -'0') * 10 + *(in+1) - '0' - 1; in+=2;
    te.tm_mday = (*in -'0') * 10 + *(in+1) - '0'; in+=2;
    te.tm_hour = (*in -'0') * 10 + *(in+1) - '0'; in+=2;
    te.tm_min  = (*in -'0') * 10 + *(in+1) - '0'; in+=2;
    te.tm_sec  = (*in -'0') * 10 + *(in+1) - '0'; in+=2;

    apr_strftime(datestr, &len, bufsize, "%b %d %T %Y GMT", &te);

    return datestr;
}

/* Calculate the sha1 hash value of data of length len. Resulting string will be
   allocated from pool and encoded as hex bytes : separated (A1:81:3F ... ). */
static const unsigned char *
sha1digest(const unsigned char *data, long len, apr_pool_t *pool)
{
    apr_sha1_ctx_t context;
    unsigned char *sha1 = apr_pcalloc(pool, APR_SHA1_DIGESTSIZE);
    unsigned char *sha1hex = apr_pcalloc(pool, APR_SHA1_DIGESTSIZE * 3);
    unsigned char *inptr = sha1, *outptr = sha1hex;
    const char al[] = "0123456789ABCDEF";
    int i;

    apr_sha1_init(&context);
    apr_sha1_update_binary(&context, data, len);
    apr_sha1_final(sha1, &context);

    /* concert to :-separated hex bytes */
    for (i = 0; i < APR_SHA1_DIGESTSIZE; i++) {
        unsigned char c = *inptr++;

        *outptr++ = al[(c & 0xf0) >> 4];
        *outptr++ = al[c & 0x0f];
        *outptr++ = ':';
    }
    *(outptr-1) = '\0';
    
    return sha1hex;
}

static apr_status_t dataref_cleanup(void *data)
{
    CFDataRef derdata = data;

    CFRelease(derdata);

    return APR_SUCCESS;
}

/* Read a Distinquished Name from a DER-encoded DN in X.509 format.
   The resulting hash table will have following keys:
   - CN, O, OU, L, ST, C, E.
   Internal use only:
   - _der
 */

apr_status_t
serf__macosxssl_read_X509_DER_DN(apr_hash_t **o, CFDataRef dndata,
                                 apr_pool_t *pool)
{
    CFDataRef dnder;
    apr_hash_t *dn;
    long consumed;
    const unsigned char *data = CFDataGetBytePtr(dndata);
    apr_status_t status;

    SERF_ERR(read_X509_DER_DistinguishedName(&dn, &dnder,
                                             data, &consumed, pool));

    apr_hash_set(dn, "_der", APR_HASH_KEY_STRING, dnder);

    *o = dn;

cleanup:
    return status;
}

/* Read all interesting data from a DER-encoded certificate in X.509 format.
   The resulting hash table will have following keys:
   - sha1
   - serial_number (TODO: not used, can be removed if that remains so. )
   - issuer: hash table with keys CN, O, OU, L, ST, C, E.
   - subject: hash table with keys CN, O, OU, L, ST, C, E. 
   - notBefore
   - notAfter
   Internal use only:
   - _issuer_der
   - _subject_der
 */
apr_status_t
serf__macosxssl_read_X509_DER_certificate(apr_hash_t **o,
                                          const macosxssl_certificate_t *cert,
                                          apr_pool_t *pool)
{
    apr_hash_t *x509_cert, *issuer, *subject;
    CFDataRef issuer_der, subject_der;
    long consumed, x509_len, value_len, signature_start;
    unsigned char tag;
    apr_status_t status;
    const char *serial, *tmp, *key, *value;
    const unsigned char *ptr, *sha1;
    int version;

    SecCertificateRef certref = cert->certref;
    CFDataRef dataref = SecCertificateCopyData(certref);
    const unsigned char *data = CFDataGetBytePtr(dataref);
    CFIndex totlen = CFDataGetLength(dataref);

    if (!totlen)
        return SERF_ERROR_SSL_CERT_FAILED;

    x509_cert = apr_hash_make(pool);

    /* SHA1 fingerprint of the full DER encoded cert. */
    sha1 = sha1digest(data, totlen, pool);
    apr_hash_set(x509_cert, "sha1", APR_HASH_KEY_STRING, sha1);
    serf__log(ST_DEBUG, __FILE__, "SHA1 fingerprint:%s.\n", sha1);

    ptr = data;
    /* 4.1.1  Certificate sequence */
    SERF_ERR(read_DER_TL(ptr, &tag, &x509_len, &consumed));
    ptr += consumed;
    signature_start = consumed;

    serf__log(ST_DEBUG, __FILE__, "Parsing DER encoding of cert length: %d.\n",
              x509_len + consumed);

    /* 4.1.2  TBSCertificate (required) */
    serf__log(ST_DEBUG, __FILE__, "---- TBSCertificate ----.\n");
    SERF_ERR(read_DER_TL(ptr, &tag, &value_len, &consumed));
    ptr += consumed; x509_len -= consumed;
    signature_start += (value_len + consumed);

    /* 4.1.2.1  Version (optional, default v1 (0x00)) */
    serf__log(ST_DEBUG, __FILE__, "---- Version ----.\n");
    SERF_ERR(read_DER_TL(ptr, &tag, &value_len, &consumed));
    if (tag == 0xa0) {
        ptr += consumed; x509_len -= consumed;
        SERF_ERR(read_DER_TLvalue(ptr, &tag, &consumed, &tmp, pool));
        version = atoi(tmp) + 1;
        ptr += consumed; x509_len -= consumed;
    } else {
        /* this was another tag than expected. Means that version wasn't set,
           used the default v1. */
        version = 1;
    }

    /* 4.1.2.2  Serial number */
    serf__log(ST_DEBUG, __FILE__, "---- Serial Number ----.\n");
    SERF_ERR(read_DER_TLvalue(ptr, &tag, &consumed, &serial, pool));
    ptr += consumed; x509_len -= consumed;
    apr_hash_set(x509_cert, "serial_number", APR_HASH_KEY_STRING, serial);

    /* 4.1.2.3  Signature (it's actually the Algorithm used to sign). */
    serf__log(ST_DEBUG, __FILE__, "---- Algorithm ----.\n");
    skip_DER_TLV(ptr, &tag, &consumed);
    ptr += consumed; x509_len -= consumed;

    /* 4.1.2.4  Issuer */
    serf__log(ST_DEBUG, __FILE__, "---- Issuer ----.\n");
    SERF_ERR(read_X509_DER_DistinguishedName(&issuer, &issuer_der,
                                             ptr, &consumed, pool));
    ptr += consumed; x509_len -= consumed;
    apr_hash_set(x509_cert, "issuer", APR_HASH_KEY_STRING, issuer);
    /* store the original der data buffer of the issuer, for internal use
       (comparison of certificates). */
    apr_hash_set(x509_cert, "_issuer_der", APR_HASH_KEY_STRING, issuer_der);

    /* 4.1.2.5  Validity */
    serf__log(ST_DEBUG, __FILE__, "---- Validity ----.\n");
    SERF_ERR(read_DER_TL(ptr, &tag, &value_len, &consumed));
    ptr += consumed; x509_len -= consumed;

    /*          notBefore */
    SERF_ERR(read_DER_TLvalue(ptr, &tag, &consumed, &tmp, pool));
    ptr += consumed; x509_len -= consumed;
    apr_hash_set(x509_cert, "notBefore", APR_HASH_KEY_STRING,
                 convert_cert_date(tmp, pool));

    /*          notAfter */
    SERF_ERR(read_DER_TLvalue(ptr, &tag, &consumed, &tmp, pool));
    ptr += consumed; x509_len -= consumed;
    apr_hash_set(x509_cert, "notAfter", APR_HASH_KEY_STRING,
                 convert_cert_date(tmp, pool));

    /* 4.1.2.6  Subject */
    serf__log(ST_DEBUG, __FILE__, "---- Subject ----.\n");
    SERF_ERR(read_X509_DER_DistinguishedName(&subject, &subject_der,
                                             ptr, &consumed, pool));
    ptr += consumed; x509_len -= consumed;
    apr_hash_set(x509_cert, "subject", APR_HASH_KEY_STRING, subject);
    /* store the original der data buffer of the subject, for internal use
       (comparison of certificates). */
    apr_hash_set(x509_cert, "_subject_der", APR_HASH_KEY_STRING, subject_der);

    /* 4.1.2.7  Subject Public Key Info */
    serf__log(ST_DEBUG, __FILE__, "---- Subject Public Key Info ----.\n");
    SERF_ERR(read_DER_TL(ptr, &tag, &value_len, &consumed));
    ptr += consumed; x509_len -= consumed;
    /*          AlgorithmIdentifier */
    SERF_ERR(read_DER_TL(ptr, &tag, &value_len, &consumed));
    ptr += consumed; x509_len -= consumed;
    SERF_ERR(read_DER_TLvalue(ptr, &tag, &consumed, &key, pool));
    ptr += consumed; x509_len -= consumed;
    SERF_ERR(read_DER_TLvalue(ptr, &tag, &consumed, &value, pool));
    ptr += consumed; x509_len -= consumed;

    /* TODO: read subjectAltName's from extensions. */

    /* Skip the remainder of TBSCertificate*/
    ptr = data + signature_start;

#if 0 /* Not needed, cleanup if this remains so. */
    /* 4.1.1.2  signatureAlgorithm (required) */
    SERF_ERR(read_DER_TL(ptr, &tag, &value_len, &consumed));
    ptr += consumed; x509_len -= consumed;
    SERF_ERR(read_DER_TLvalue(ptr, &tag, &consumed, &key, pool));
    ptr += consumed; x509_len -= consumed;
    SERF_ERR(read_DER_TLvalue(ptr, &tag, &consumed, &value, pool));
    ptr += consumed; x509_len -= consumed;

    /* 4.1.1.3  signatureValue (required) */
    SERF_ERR(read_DER_TLvalue(ptr, &tag, &consumed, &value, pool));
    ptr += consumed; x509_len -= consumed;

    serf__log(ST_DEBUG, __FILE__, "Remaining to read: %d.\n", x509_len);
#endif

    *o = x509_cert;

    apr_pool_cleanup_register(pool, issuer_der, dataref_cleanup,
                              dataref_cleanup);
    apr_pool_cleanup_register(pool, subject_der, dataref_cleanup,
                              dataref_cleanup);

    return APR_SUCCESS;

cleanup:
    CFRelease(dataref);

    return status;
}

#endif /* SERF_HAVE_MACOSXSSL */
