/*
 *  Convert PEM to DER
 *
 *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
 *
 *  This file is part of mbed TLS (https://tls.mbed.org)
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif

#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
#include <stdio.h>
#define mbedtls_free       free
#define mbedtls_calloc    calloc
#define mbedtls_printf     printf
#endif

#if defined(MBEDTLS_BASE64_C) && defined(MBEDTLS_FS_IO)
#include "mbedtls/error.h"
#include "mbedtls/base64.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#endif

#define DFL_FILENAME            "file.pem"
#define DFL_OUTPUT_FILENAME     "file.der"

#define USAGE \
    "\n usage: pem2der param=<>...\n"                   \
    "\n acceptable parameters:\n"                       \
    "    filename=%%s         default: file.pem\n"      \
    "    output_file=%%s      default: file.der\n"      \
    "\n"

#if !defined(MBEDTLS_BASE64_C) || !defined(MBEDTLS_FS_IO)
int main( void )
{
    mbedtls_printf("MBEDTLS_BASE64_C and/or MBEDTLS_FS_IO not defined.\n");
    return( 0 );
}
#else
/*
 * global options
 */
struct options
{
    const char *filename;       /* filename of the input file             */
    const char *output_file;    /* where to store the output              */
} opt;

int convert_pem_to_der( const unsigned char *input, size_t ilen,
                        unsigned char *output, size_t *olen )
{
    int ret;
    const unsigned char *s1, *s2, *end = input + ilen;
    size_t len = 0;

    s1 = (unsigned char *) strstr( (const char *) input, "-----BEGIN" );
    if( s1 == NULL )
        return( -1 );

    s2 = (unsigned char *) strstr( (const char *) input, "-----END" );
    if( s2 == NULL )
        return( -1 );

    s1 += 10;
    while( s1 < end && *s1 != '-' )
        s1++;
    while( s1 < end && *s1 == '-' )
        s1++;
    if( *s1 == '\r' ) s1++;
    if( *s1 == '\n' ) s1++;

    if( s2 <= s1 || s2 > end )
        return( -1 );

    ret = mbedtls_base64_decode( NULL, 0, &len, (const unsigned char *) s1, s2 - s1 );
    if( ret == MBEDTLS_ERR_BASE64_INVALID_CHARACTER )
        return( ret );

    if( len > *olen )
        return( -1 );

    if( ( ret = mbedtls_base64_decode( output, len, &len, (const unsigned char *) s1,
                               s2 - s1 ) ) != 0 )
    {
        return( ret );
    }

    *olen = len;

    return( 0 );
}

/*
 * Load all data from a file into a given buffer.
 */
static int load_file( const char *path, unsigned char **buf, size_t *n )
{
    FILE *f;
    long size;

    if( ( f = fopen( path, "rb" ) ) == NULL )
        return( -1 );

    fseek( f, 0, SEEK_END );
    if( ( size = ftell( f ) ) == -1 )
    {
        fclose( f );
        return( -1 );
    }
    fseek( f, 0, SEEK_SET );

    *n = (size_t) size;

    if( *n + 1 == 0 ||
        ( *buf = mbedtls_calloc( 1, *n + 1 ) ) == NULL )
    {
        fclose( f );
        return( -1 );
    }

    if( fread( *buf, 1, *n, f ) != *n )
    {
        fclose( f );
        free( *buf );
        *buf = NULL;
        return( -1 );
    }

    fclose( f );

    (*buf)[*n] = '\0';

    return( 0 );
}

/*
 * Write buffer to a file
 */
static int write_file( const char *path, unsigned char *buf, size_t n )
{
    FILE *f;

    if( ( f = fopen( path, "wb" ) ) == NULL )
        return( -1 );

    if( fwrite( buf, 1, n, f ) != n )
    {
        fclose( f );
        return( -1 );
    }

    fclose( f );
    return( 0 );
}

int main( int argc, char *argv[] )
{
    int ret = 0;
    unsigned char *pem_buffer = NULL;
    unsigned char der_buffer[4096];
    char buf[1024];
    size_t pem_size, der_size = sizeof(der_buffer);
    int i;
    char *p, *q;

    /*
     * Set to sane values
     */
    memset( buf, 0, sizeof(buf) );
    memset( der_buffer, 0, sizeof(der_buffer) );

    if( argc == 0 )
    {
    usage:
        mbedtls_printf( USAGE );
        goto exit;
    }

    opt.filename            = DFL_FILENAME;
    opt.output_file         = DFL_OUTPUT_FILENAME;

    for( i = 1; i < argc; i++ )
    {

        p = argv[i];
        if( ( q = strchr( p, '=' ) ) == NULL )
            goto usage;
        *q++ = '\0';

        if( strcmp( p, "filename" ) == 0 )
            opt.filename = q;
        else if( strcmp( p, "output_file" ) == 0 )
            opt.output_file = q;
        else
            goto usage;
    }

    /*
     * 1.1. Load the PEM file
     */
    mbedtls_printf( "\n  . Loading the PEM file ..." );
    fflush( stdout );

    ret = load_file( opt.filename, &pem_buffer, &pem_size );

    if( ret != 0 )
    {
#ifdef MBEDTLS_ERROR_C
        mbedtls_strerror( ret, buf, 1024 );
#endif
        mbedtls_printf( " failed\n  !  load_file returned %d - %s\n\n", ret, buf );
        goto exit;
    }

    mbedtls_printf( " ok\n" );

    /*
     * 1.2. Convert from PEM to DER
     */
    mbedtls_printf( "  . Converting from PEM to DER ..." );
    fflush( stdout );

    if( ( ret = convert_pem_to_der( pem_buffer, pem_size, der_buffer, &der_size ) ) != 0 )
    {
#ifdef MBEDTLS_ERROR_C
        mbedtls_strerror( ret, buf, 1024 );
#endif
        mbedtls_printf( " failed\n  !  convert_pem_to_der %d - %s\n\n", ret, buf );
        goto exit;
    }

    mbedtls_printf( " ok\n" );

    /*
     * 1.3. Write the DER file
     */
    mbedtls_printf( "  . Writing the DER file ..." );
    fflush( stdout );

    ret = write_file( opt.output_file, der_buffer, der_size );

    if( ret != 0 )
    {
#ifdef MBEDTLS_ERROR_C
        mbedtls_strerror( ret, buf, 1024 );
#endif
        mbedtls_printf( " failed\n  !  write_file returned %d - %s\n\n", ret, buf );
        goto exit;
    }

    mbedtls_printf( " ok\n" );

exit:
    free( pem_buffer );

#if defined(_WIN32)
    mbedtls_printf( "  + Press Enter to exit this program.\n" );
    fflush( stdout ); getchar();
#endif

    return( ret );
}
#endif /* MBEDTLS_BASE64_C && MBEDTLS_FS_IO */
