/* certinfo.c  --  Functions to parse and process the X509 TLS id string
 *
 *  GPLv2 only - Copyright (C) 2008 - 2012
 *               David Sommerseth <dazo@users.sourceforge.net>
 *
 *  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; version 2
 *  of the License.
 *
 *  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.
 *
 */

/**
 * @file   certinfo.c
 * @author David Sommerseth <dazo@users.sourceforge.net>
 * @date   2008-08-06
 *
 * @brief  Functions for parsing X.509 subject information
 *
 */


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

#include <eurephia_nullsafe.h>
#include <certinfo.h>

/**
 * Simple strcmp() wrapper, which makes it NULL safe.
 *
 * @param s input value
 * @param v compare value
 *
 * @return Returns 1 if s and v are equal, otherwise 0.
 */
#define comp_attrib(s, v) ( (v == NULL || strlen_nullsafe(v) < 1) ? 0 : (strcmp(v, s) == 0) )

/**
 * Parses a X.509 subject string into a certinfo structure
 *
 * @param input  String containing a X.509 subject line
 *
 * @return Pointer to a certinfo structure containing the information
 */
certinfo *parse_tlsid(const char *input) {
        char tmp[130], *mainp, *origptr, *sub, *tok, *tok2;
        certinfo *ret = NULL;

        if( (input == NULL) || strlen(input) < 5)
                return NULL;

        ret = (certinfo *) malloc_nullsafe(NULL, sizeof(certinfo)+2);
        memset(&tmp, 0, 130);

        mainp = strdup(input);
        origptr = mainp;
        tok = strsep(&mainp, "/\0");
        while( tok != NULL ) {
                if( (tok != NULL) && (strlen(tok) > 0 ) ) {
                        sub = strdup(tok);
                        tok2 = strsep(&sub, "=\0");

                        if( comp_attrib("O\0", tok2) ) {
                                ret->org = strdup(strsep(&sub, "=\0"));
                        } else if( comp_attrib("CN\0", tok2) ) {
                                ret->common_name = strdup(strsep(&sub, "=\0"));
                        } else if( comp_attrib("emailAddress\0", tok2) ) {
                                ret->email = strdup(strsep(&sub, "=\0"));
                        }
                        if( tok2 != NULL ) {
                                free(tok2); tok2 = NULL;
                        }
                }
                tok = strsep(&mainp, "/\0");
        }
        free(origptr); mainp = NULL; origptr = NULL;

        /* Make sure we at least have empty NULL terminated strings */
        if( ret->org == NULL ) {
                ret->org = strdup("\0");
        }
        if( ret->common_name == NULL ) {
                ret->common_name = strdup("\0");
        }
        if( ret->email == NULL ) {
                ret->email = strdup("\0");
        }

        return ret;
}


/**
 * Frees up the memory used by a certinfo structure
 *
 * @param p Pointer to a certinfo structure to be freed
 */
void free_certinfo(certinfo *p) {
        if( p == NULL )
                return;

        if( p->digest != NULL )
                free(p->digest);
        if( p->org != NULL )
                free(p->org);
        if( p->common_name != NULL )
                free(p->common_name);
        if( p->email != NULL )
                free(p->email);

        free(p);
}
