/** BEGIN COPYRIGHT BLOCK
 * Copyright (C) 2001 Sun Microsystems, Inc.  Used by permission.
 * Copyright (C) 2005 Red Hat, Inc.
 * All rights reserved.
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation version
 * 2.1 of the License.
 *                                                                                  
 * This library 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
 * Lesser General Public License for more details.
 *                                                                                  
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 * END COPYRIGHT BLOCK **/
/*
 * Description (certmgt.c)
 *
 *        This module contains routines used by administration CGI
 *        programs to access certificate databases.
 */


#include "libadminutil/admutil.h"

#include "key.h"
#include "cert.h"
#include "certdb.h"
#include "secder.h"
#include "pk11func.h"

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


/* Get a representative string for a given SECName */
PR_IMPLEMENT(char *)
cmgGetNameDesc(CERTName * name)
{
    char * s;

    s = CERT_GetCommonName(name);
    if (s == 0) {
        s = CERT_GetOrgUnitName(name);
        if (s == 0) {
            s = CERT_GetOrgName(name);
            if (s == 0) {
                CERT_GetLocalityName(name);
                if (s == 0) {
                    s = CERT_GetStateName(name);
                    if (s == 0) s = "";
                }
            }
        }
      }

    return PORT_Strdup(s);
}


static SECStatus cmgShowCrlRow(CERTSignedCrl *crl)
{
    char * datestr;
    char * nn;
/*    SECCertTimeValidity validity; */

    nn = cmgGetNameDesc(&crl->crl.name);
    if (!nn) {
        return SECFailure;
    }

    datestr = DER_UTCTimeToAscii(&crl->crl.nextUpdate);
    if (!datestr) {
        return SECFailure;
    }
/*    validity = SEC_CheckCrlTimes(&crl->crl, time(NULL)); */

    printf("%s;%s\n", nn, datestr);

    PORT_Free(datestr);

    return SECSuccess;
}


PR_IMPLEMENT(int)
cmgShowCrls(CERTCertDBHandle *handle, int list_type)
{

  CERTCrlHeadNode *CrlListHead;
  CERTCrlNode *node;
  SECStatus rv;

  rv = SEC_LookupCrls(handle, &CrlListHead, list_type);
  if(rv != SECSuccess) return rv;

  for(node = CrlListHead->first; node != NULL; node = node->next) {
      cmgShowCrlRow(node->crl);
  }

  return SECSuccess;
}


PR_IMPLEMENT(char *)
cmgHTMLCrlInfo(CERTSignedCrl *crl)
{
    char *issuer = NULL;
    char *notBefore = NULL;
    char *notAfter = NULL;

#define NCHARPERLINE 50
#define NLINES 20
    char *outputBuffer = NULL;
    
    if (!crl) {
        goto bail;
    }

    issuer = CERT_FormatName(&crl->crl.name);
    notBefore = (char *)DER_UTCTimeToAscii(&crl->crl.lastUpdate);
    notAfter = (char *)DER_UTCTimeToAscii(&crl->crl.nextUpdate);

    if (!issuer || !notBefore || !notAfter) {
        goto bail;
    }

    /* reformat dates */
    notBefore[10] = ',';
    notAfter[10] = ',';
    if ( notBefore[8] == '0' ) {
        notBefore[8] = ' ';
    }
    if ( notAfter[8] == '0' ) {
        notAfter[8] = ' ';
    }

    outputBuffer = PR_smprintf("ISSUER=%s\nNOTBEFORE=%s\nNOTAFTER=%s\n",
                               issuer, notBefore, notAfter);
    
bail:
    if ( issuer ) {
        PORT_Free(issuer);
    }
    
    if ( notBefore ) {
        PORT_Free(notBefore);
    }
    
    if ( notAfter ) {
        PORT_Free(notAfter);
    }
    
    return(outputBuffer);
}


static SECStatus cmgFindCrl(CERTSignedCrl *crl, char *name)
{
    char * nn;

    nn = cmgGetNameDesc(&crl->crl.name);
    if (!nn) {
        return SECFailure;
    }

    if (strcmp(nn,name) == 0) {
      return SECSuccess; /* We found what we were looking for, 
                          * break from our loop */
    }
    return SECFailure;
}


/* 
 * cmgFindCrlByName(CERTCertDBHandle *, char *, int)
 *
 * Search both CRL's and CKL's for the list with name 'name'.
 */

PR_IMPLEMENT(CERTSignedCrl *)
cmgFindCrlByName(CERTCertDBHandle *handle, char *name, int list_type) 
{

  CERTCrlHeadNode *CrlListHead;
  CERTCrlNode *node;
  SECStatus rv;

  if((!name) || (!handle))
    return NULL;

  rv = SEC_LookupCrls(handle, &CrlListHead, list_type);
  if(rv != SECSuccess) return NULL;

  for(node = CrlListHead->first; node != NULL; node = node->next) {
      if(cmgFindCrl(node->crl, name) == SECSuccess)
        break;
  }

  if(node)
    /* OK, node contains the "dummy" crl - get the real one now */
    return(SEC_FindCrlByName(handle, &node->crl->crl.derName, list_type));
  else
    return NULL;
}
