Back to index

lightning-sunbird  0.9+nobinonly
Classes | Defines | Typedefs | Enumerations | Functions | Variables
crmfcgi.c File Reference
#include "seccomon.h"
#include "nss.h"
#include "key.h"
#include "cert.h"
#include "pk11func.h"
#include "secmod.h"
#include "cmmf.h"
#include "crmf.h"
#include "base64.h"
#include "secasn1.h"
#include "cryptohi.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

Go to the source code of this file.

Classes

struct  CGIVariableStr
struct  CGIVarTableStr
struct  CertResponseInfoStr
struct  ChallengeCreationInfoStr

Defines

#define DEFAULT_ALLOC_SIZE   200
#define DEFAULT_CGI_VARS   20

Typedefs

typedef struct CGIVariableStr CGIVariable
typedef struct CGIVarTableStr CGIVarTable
typedef struct CertResponseInfoStr CertResponseInfo
typedef struct
ChallengeCreationInfoStr 
ChallengeCreationInfo

Enumerations

enum  ErrorCode {
  NO_ERROR = 0, NSS_INIT_FAILED, AUTH_FAILED, REQ_CGI_VAR_NOT_PRESENT,
  CRMF_REQ_NOT_PRESENT, BAD_ASCII_FOR_REQ, CGI_VAR_MISSING, COULD_NOT_FIND_CA,
  COULD_NOT_DECODE_REQS, OUT_OF_MEMORY, ERROR_RETRIEVING_REQUEST_MSG, ERROR_RETRIEVING_CERT_REQUEST,
  ERROR_RETRIEVING_SUBJECT_FROM_REQ, ERROR_RETRIEVING_PUBLIC_KEY_FROM_REQ, ERROR_CREATING_NEW_CERTIFICATE, COULD_NOT_START_EXTENSIONS,
  ERROR_RETRIEVING_EXT_FROM_REQ, ERROR_ADDING_EXT_TO_CERT, ERROR_ENDING_EXTENSIONS, COULD_NOT_FIND_ISSUER_PRIVATE_KEY,
  UNSUPPORTED_SIGN_OPERATION_FOR_ISSUER, ERROR_SETTING_SIGN_ALG, ERROR_ENCODING_NEW_CERT, ERROR_SIGNING_NEW_CERT,
  ERROR_CREATING_CERT_REP_CONTENT, ERROR_CREATING_SINGLE_CERT_RESPONSE, ERROR_SETTING_CERT_RESPONSES, ERROR_CREATING_CA_LIST,
  ERROR_ADDING_ISSUER_TO_CA_LIST, ERROR_ENCODING_CERT_REP_CONTENT, NO_POP_FOR_REQUEST, UNSUPPORTED_POP,
  ERROR_RETRIEVING_POP_SIGN_KEY, ERROR_RETRIEVING_ALG_ID_FROM_SIGN_KEY, ERROR_RETRIEVING_SIGNATURE_FROM_POP_SIGN_KEY, DO_CHALLENGE_RESPONSE,
  ERROR_RETRIEVING_PUB_KEY_FROM_NEW_CERT, ERROR_ENCODING_CERT_REQ_FOR_POP, ERROR_VERIFYING_SIGNATURE_POP, ERROR_RETRIEVING_PUB_KEY_FOR_CHALL,
  ERROR_CREATING_EMPTY_CHAL_CONTENT, ERROR_EXTRACTING_GEN_NAME_FROM_ISSUER, ERROR_SETTING_CHALLENGE, ERROR_ENCODING_CHALL,
  ERROR_CONVERTING_CHALL_TO_BASE64, ERROR_CONVERTING_RESP_FROM_CHALL_TO_BIN, ERROR_CREATING_KEY_RESP_FROM_DER, ERROR_RETRIEVING_CLIENT_RESPONSE_TO_CHALLENGE,
  ERROR_RETURNED_CHALL_NOT_VALUE_EXPECTED, ERROR_GETTING_KEY_ENCIPHERMENT, ERROR_NO_POP_FOR_PRIVKEY, ERROR_UNSUPPORTED_POPOPRIVKEY_TYPE,
  NO_ERROR = 0, NSS_INIT_FAILED, AUTH_FAILED, REQ_CGI_VAR_NOT_PRESENT,
  CRMF_REQ_NOT_PRESENT, BAD_ASCII_FOR_REQ, CGI_VAR_MISSING, COULD_NOT_FIND_CA,
  COULD_NOT_DECODE_REQS, OUT_OF_MEMORY, ERROR_RETRIEVING_REQUEST_MSG, ERROR_RETRIEVING_CERT_REQUEST,
  ERROR_RETRIEVING_SUBJECT_FROM_REQ, ERROR_RETRIEVING_PUBLIC_KEY_FROM_REQ, ERROR_CREATING_NEW_CERTIFICATE, COULD_NOT_START_EXTENSIONS,
  ERROR_RETRIEVING_EXT_FROM_REQ, ERROR_ADDING_EXT_TO_CERT, ERROR_ENDING_EXTENSIONS, COULD_NOT_FIND_ISSUER_PRIVATE_KEY,
  UNSUPPORTED_SIGN_OPERATION_FOR_ISSUER, ERROR_SETTING_SIGN_ALG, ERROR_ENCODING_NEW_CERT, ERROR_SIGNING_NEW_CERT,
  ERROR_CREATING_CERT_REP_CONTENT, ERROR_CREATING_SINGLE_CERT_RESPONSE, ERROR_SETTING_CERT_RESPONSES, ERROR_CREATING_CA_LIST,
  ERROR_ADDING_ISSUER_TO_CA_LIST, ERROR_ENCODING_CERT_REP_CONTENT, NO_POP_FOR_REQUEST, UNSUPPORTED_POP,
  ERROR_RETRIEVING_POP_SIGN_KEY, ERROR_RETRIEVING_ALG_ID_FROM_SIGN_KEY, ERROR_RETRIEVING_SIGNATURE_FROM_POP_SIGN_KEY, DO_CHALLENGE_RESPONSE,
  ERROR_RETRIEVING_PUB_KEY_FROM_NEW_CERT, ERROR_ENCODING_CERT_REQ_FOR_POP, ERROR_VERIFYING_SIGNATURE_POP, ERROR_RETRIEVING_PUB_KEY_FOR_CHALL,
  ERROR_CREATING_EMPTY_CHAL_CONTENT, ERROR_EXTRACTING_GEN_NAME_FROM_ISSUER, ERROR_SETTING_CHALLENGE, ERROR_ENCODING_CHALL,
  ERROR_CONVERTING_CHALL_TO_BASE64, ERROR_CONVERTING_RESP_FROM_CHALL_TO_BIN, ERROR_CREATING_KEY_RESP_FROM_DER, ERROR_RETRIEVING_CLIENT_RESPONSE_TO_CHALLENGE,
  ERROR_RETURNED_CHALL_NOT_VALUE_EXPECTED, ERROR_GETTING_KEY_ENCIPHERMENT, ERROR_NO_POP_FOR_PRIVKEY, ERROR_UNSUPPORTED_POPOPRIVKEY_TYPE
}

Functions

const char * CGITableFindValue (CGIVarTable *varTable, const char *key)
void spitOutHeaders (void)
void dumpRequest (CGIVarTable *varTable)
void echo_request (CGIVarTable *varTable)
void processVariable (CGIVariable *var)
char * parseNextVariable (CGIVarTable *varTable, char *form_output)
void ParseInputVariables (CGIVarTable *varTable, char *form_output)
char * passwordCallback (PK11SlotInfo *slot, PRBool retry, void *arg)
ErrorCode initNSS (CGIVarTable *varTable)
void dumpErrorMessage (ErrorCode errNum)
ErrorCode initOldCertReq (CERTCertificateRequest *oldCertReq, CERTName *subject, CERTSubjectPublicKeyInfo *spki)
ErrorCode addExtensions (CERTCertificate *newCert, CRMFCertRequest *certReq)
void writeOutItem (const char *filePath, SECItem *der)
ErrorCode createNewCert (CERTCertificate **issuedCert, CERTCertificateRequest *oldCertReq, CRMFCertReqMsg *currReq, CRMFCertRequest *certReq, CERTCertificate *issuerCert, CGIVarTable *varTable)
void formatCMMFResponse (char *nickname, char *base64Response)
void spitOutCMMFResponse (char *nickname, char *base64Response)
char * getNickname (CERTCertificate *cert)
ErrorCode createCMMFResponse (CertResponseInfo *issuedCerts, int numCerts, CERTCertificate *issuerCert, char **base64der)
ErrorCode issueCerts (CertResponseInfo *issuedCerts, int numCerts, CERTCertificate *issuerCert)
ErrorCode verifySignature (CGIVarTable *varTable, CRMFCertReqMsg *currReq, CRMFCertRequest *certReq, CERTCertificate *newCert)
ErrorCode doChallengeResponse (CGIVarTable *varTable, CRMFCertReqMsg *currReq, CRMFCertRequest *certReq, CERTCertificate *newCert, ChallengeCreationInfo *challs, int *numChall)
ErrorCode doProofOfPossession (CGIVarTable *varTable, CRMFCertReqMsg *currReq, CRMFCertRequest *certReq, CERTCertificate *newCert, ChallengeCreationInfo *challs, int *numChall)
void convertB64ToJS (char *base64)
void formatChallenge (char *chall64, char *certRepContentDER, ChallengeCreationInfo *challInfo, int numChalls)
void spitOutChallenge (char *chall64, char *certRepContentDER, ChallengeCreationInfo *challInfo, int numChalls, char *nickname)
ErrorCode issueChallenge (CertResponseInfo *issuedCerts, int numCerts, ChallengeCreationInfo *challInfo, int numChalls, CERTCertificate *issuer, CGIVarTable *varTable)
ErrorCode processRequest (CGIVarTable *varTable)
ErrorCode processChallengeResponse (CGIVarTable *varTable, const char *certRepContent)
int main ()
 main()

Variables

char * missingVar = NULL

Class Documentation

struct CGIVariableStr

Definition at line 55 of file crmfcgi.c.

Class Members
char * name
char * value
struct CGIVarTableStr

Definition at line 60 of file crmfcgi.c.

Collaboration diagram for CGIVarTableStr:
Class Members
int numAlloc
int numVars
CGIVariable ** variables
struct CertResponseInfoStr

Definition at line 66 of file crmfcgi.c.

Class Members
CERTCertificate * cert
long certReqID
struct ChallengeCreationInfoStr

Definition at line 71 of file crmfcgi.c.

Class Members
SECKEYPublicKey * pubKey
long random

Define Documentation

Definition at line 52 of file crmfcgi.c.

Definition at line 53 of file crmfcgi.c.


Typedef Documentation

typedef struct CGIVariableStr CGIVariable
typedef struct CGIVarTableStr CGIVarTable

Enumeration Type Documentation

enum ErrorCode
Enumerator:
NO_ERROR 
NSS_INIT_FAILED 
AUTH_FAILED 
REQ_CGI_VAR_NOT_PRESENT 
CRMF_REQ_NOT_PRESENT 
BAD_ASCII_FOR_REQ 
CGI_VAR_MISSING 
COULD_NOT_FIND_CA 
COULD_NOT_DECODE_REQS 
OUT_OF_MEMORY 
ERROR_RETRIEVING_REQUEST_MSG 
ERROR_RETRIEVING_CERT_REQUEST 
ERROR_RETRIEVING_SUBJECT_FROM_REQ 
ERROR_RETRIEVING_PUBLIC_KEY_FROM_REQ 
ERROR_CREATING_NEW_CERTIFICATE 
COULD_NOT_START_EXTENSIONS 
ERROR_RETRIEVING_EXT_FROM_REQ 
ERROR_ADDING_EXT_TO_CERT 
ERROR_ENDING_EXTENSIONS 
COULD_NOT_FIND_ISSUER_PRIVATE_KEY 
UNSUPPORTED_SIGN_OPERATION_FOR_ISSUER 
ERROR_SETTING_SIGN_ALG 
ERROR_ENCODING_NEW_CERT 
ERROR_SIGNING_NEW_CERT 
ERROR_CREATING_CERT_REP_CONTENT 
ERROR_CREATING_SINGLE_CERT_RESPONSE 
ERROR_SETTING_CERT_RESPONSES 
ERROR_CREATING_CA_LIST 
ERROR_ADDING_ISSUER_TO_CA_LIST 
ERROR_ENCODING_CERT_REP_CONTENT 
NO_POP_FOR_REQUEST 
UNSUPPORTED_POP 
ERROR_RETRIEVING_POP_SIGN_KEY 
ERROR_RETRIEVING_ALG_ID_FROM_SIGN_KEY 
ERROR_RETRIEVING_SIGNATURE_FROM_POP_SIGN_KEY 
DO_CHALLENGE_RESPONSE 
ERROR_RETRIEVING_PUB_KEY_FROM_NEW_CERT 
ERROR_ENCODING_CERT_REQ_FOR_POP 
ERROR_VERIFYING_SIGNATURE_POP 
ERROR_RETRIEVING_PUB_KEY_FOR_CHALL 
ERROR_CREATING_EMPTY_CHAL_CONTENT 
ERROR_EXTRACTING_GEN_NAME_FROM_ISSUER 
ERROR_SETTING_CHALLENGE 
ERROR_ENCODING_CHALL 
ERROR_CONVERTING_CHALL_TO_BASE64 
ERROR_CONVERTING_RESP_FROM_CHALL_TO_BIN 
ERROR_CREATING_KEY_RESP_FROM_DER 
ERROR_RETRIEVING_CLIENT_RESPONSE_TO_CHALLENGE 
ERROR_RETURNED_CHALL_NOT_VALUE_EXPECTED 
ERROR_GETTING_KEY_ENCIPHERMENT 
ERROR_NO_POP_FOR_PRIVKEY 
ERROR_UNSUPPORTED_POPOPRIVKEY_TYPE 
NO_ERROR 
NSS_INIT_FAILED 
AUTH_FAILED 
REQ_CGI_VAR_NOT_PRESENT 
CRMF_REQ_NOT_PRESENT 
BAD_ASCII_FOR_REQ 
CGI_VAR_MISSING 
COULD_NOT_FIND_CA 
COULD_NOT_DECODE_REQS 
OUT_OF_MEMORY 
ERROR_RETRIEVING_REQUEST_MSG 
ERROR_RETRIEVING_CERT_REQUEST 
ERROR_RETRIEVING_SUBJECT_FROM_REQ 
ERROR_RETRIEVING_PUBLIC_KEY_FROM_REQ 
ERROR_CREATING_NEW_CERTIFICATE 
COULD_NOT_START_EXTENSIONS 
ERROR_RETRIEVING_EXT_FROM_REQ 
ERROR_ADDING_EXT_TO_CERT 
ERROR_ENDING_EXTENSIONS 
COULD_NOT_FIND_ISSUER_PRIVATE_KEY 
UNSUPPORTED_SIGN_OPERATION_FOR_ISSUER 
ERROR_SETTING_SIGN_ALG 
ERROR_ENCODING_NEW_CERT 
ERROR_SIGNING_NEW_CERT 
ERROR_CREATING_CERT_REP_CONTENT 
ERROR_CREATING_SINGLE_CERT_RESPONSE 
ERROR_SETTING_CERT_RESPONSES 
ERROR_CREATING_CA_LIST 
ERROR_ADDING_ISSUER_TO_CA_LIST 
ERROR_ENCODING_CERT_REP_CONTENT 
NO_POP_FOR_REQUEST 
UNSUPPORTED_POP 
ERROR_RETRIEVING_POP_SIGN_KEY 
ERROR_RETRIEVING_ALG_ID_FROM_SIGN_KEY 
ERROR_RETRIEVING_SIGNATURE_FROM_POP_SIGN_KEY 
DO_CHALLENGE_RESPONSE 
ERROR_RETRIEVING_PUB_KEY_FROM_NEW_CERT 
ERROR_ENCODING_CERT_REQ_FOR_POP 
ERROR_VERIFYING_SIGNATURE_POP 
ERROR_RETRIEVING_PUB_KEY_FOR_CHALL 
ERROR_CREATING_EMPTY_CHAL_CONTENT 
ERROR_EXTRACTING_GEN_NAME_FROM_ISSUER 
ERROR_SETTING_CHALLENGE 
ERROR_ENCODING_CHALL 
ERROR_CONVERTING_CHALL_TO_BASE64 
ERROR_CONVERTING_RESP_FROM_CHALL_TO_BIN 
ERROR_CREATING_KEY_RESP_FROM_DER 
ERROR_RETRIEVING_CLIENT_RESPONSE_TO_CHALLENGE 
ERROR_RETURNED_CHALL_NOT_VALUE_EXPECTED 
ERROR_GETTING_KEY_ENCIPHERMENT 
ERROR_NO_POP_FOR_PRIVKEY 
ERROR_UNSUPPORTED_POPOPRIVKEY_TYPE 

Definition at line 81 of file crmfcgi.c.

             {
  NO_ERROR = 0,
  NSS_INIT_FAILED,
  AUTH_FAILED,
  REQ_CGI_VAR_NOT_PRESENT,
  CRMF_REQ_NOT_PRESENT,
  BAD_ASCII_FOR_REQ,
  CGI_VAR_MISSING,
  COULD_NOT_FIND_CA,
  COULD_NOT_DECODE_REQS,
  OUT_OF_MEMORY,
  ERROR_RETRIEVING_REQUEST_MSG,
  ERROR_RETRIEVING_CERT_REQUEST,
  ERROR_RETRIEVING_SUBJECT_FROM_REQ,
  ERROR_RETRIEVING_PUBLIC_KEY_FROM_REQ,
  ERROR_CREATING_NEW_CERTIFICATE,
  COULD_NOT_START_EXTENSIONS,
  ERROR_RETRIEVING_EXT_FROM_REQ,
  ERROR_ADDING_EXT_TO_CERT,
  ERROR_ENDING_EXTENSIONS,
  COULD_NOT_FIND_ISSUER_PRIVATE_KEY,
  UNSUPPORTED_SIGN_OPERATION_FOR_ISSUER,
  ERROR_SETTING_SIGN_ALG,
  ERROR_ENCODING_NEW_CERT,
  ERROR_SIGNING_NEW_CERT,
  ERROR_CREATING_CERT_REP_CONTENT,
  ERROR_CREATING_SINGLE_CERT_RESPONSE,
  ERROR_SETTING_CERT_RESPONSES,
  ERROR_CREATING_CA_LIST,
  ERROR_ADDING_ISSUER_TO_CA_LIST,
  ERROR_ENCODING_CERT_REP_CONTENT,
  NO_POP_FOR_REQUEST,
  UNSUPPORTED_POP,
  ERROR_RETRIEVING_POP_SIGN_KEY,
  ERROR_RETRIEVING_ALG_ID_FROM_SIGN_KEY,
  ERROR_RETRIEVING_SIGNATURE_FROM_POP_SIGN_KEY,
  DO_CHALLENGE_RESPONSE,
  ERROR_RETRIEVING_PUB_KEY_FROM_NEW_CERT,
  ERROR_ENCODING_CERT_REQ_FOR_POP,
  ERROR_VERIFYING_SIGNATURE_POP,
  ERROR_RETRIEVING_PUB_KEY_FOR_CHALL,
  ERROR_CREATING_EMPTY_CHAL_CONTENT,
  ERROR_EXTRACTING_GEN_NAME_FROM_ISSUER,
  ERROR_SETTING_CHALLENGE,
  ERROR_ENCODING_CHALL,
  ERROR_CONVERTING_CHALL_TO_BASE64,
  ERROR_CONVERTING_RESP_FROM_CHALL_TO_BIN,
  ERROR_CREATING_KEY_RESP_FROM_DER,
  ERROR_RETRIEVING_CLIENT_RESPONSE_TO_CHALLENGE,
  ERROR_RETURNED_CHALL_NOT_VALUE_EXPECTED,
  ERROR_GETTING_KEY_ENCIPHERMENT,
  ERROR_NO_POP_FOR_PRIVKEY,
  ERROR_UNSUPPORTED_POPOPRIVKEY_TYPE
} ErrorCode;

Function Documentation

ErrorCode addExtensions ( CERTCertificate *  newCert,
CRMFCertRequest *  certReq 
)

Definition at line 328 of file crmfcgi.c.

{
  int numExtensions, i;
  void *extHandle;
  ErrorCode rv = NO_ERROR;
  CRMFCertExtension *ext;
  SECStatus srv;

  numExtensions = CRMF_CertRequestGetNumberOfExtensions(certReq);
  if (numExtensions == 0) {
    /* No extensions to add */
    return NO_ERROR;
  }
  extHandle = CERT_StartCertExtensions(newCert);
  if (extHandle == NULL) {
    rv = COULD_NOT_START_EXTENSIONS;
    goto loser;
  }
  for (i=0; i<numExtensions; i++) {
    ext = CRMF_CertRequestGetExtensionAtIndex(certReq, i);
    if (ext == NULL) {
      rv = ERROR_RETRIEVING_EXT_FROM_REQ;
    }
    srv = CERT_AddExtension(extHandle, CRMF_CertExtensionGetOidTag(ext),
                         CRMF_CertExtensionGetValue(ext),
                         CRMF_CertExtensionGetIsCritical(ext), PR_FALSE);
    if (srv != SECSuccess) {
      rv = ERROR_ADDING_EXT_TO_CERT;
    }
  }
  srv = CERT_FinishExtensions(extHandle);
  if (srv != SECSuccess) {
    rv = ERROR_ENDING_EXTENSIONS;
    goto loser;
  }
  return NO_ERROR;
 loser:
  return rv;
}

Here is the call graph for this function:

const char* CGITableFindValue ( CGIVarTable varTable,
const char *  key 
)
void convertB64ToJS ( char *  base64)

Definition at line 750 of file crmfcgi.c.

{
  int i;

  for (i=0; base64[i] != '\0'; i++) {
    if (base64[i] == '\n') {
      printf ("\\n");
    }else {
      printf ("%c", base64[i]);
    }
  }
}
ErrorCode createCMMFResponse ( CertResponseInfo issuedCerts,
int  numCerts,
CERTCertificate *  issuerCert,
char **  base64der 
)

Definition at line 525 of file crmfcgi.c.

{
 CMMFCertRepContent *certRepContent=NULL;
  ErrorCode rv = NO_ERROR;
  CMMFCertResponse **responses, *currResponse;
  CERTCertList *caList;
  int i;
  SECStatus srv;
  PRArenaPool *poolp;
  SECItem *der;

  certRepContent = CMMF_CreateCertRepContent();
  if (certRepContent == NULL) {
    rv = ERROR_CREATING_CERT_REP_CONTENT;
    goto loser;
  }
  responses = PORT_NewArray(CMMFCertResponse*, numCerts);
  if (responses == NULL) {
    rv = OUT_OF_MEMORY;
    goto loser;
  }
  for (i=0; i<numCerts;i++) {
    responses[i] = currResponse = 
      CMMF_CreateCertResponse(issuedCerts[i].certReqID);
    if (currResponse == NULL) {
      rv = ERROR_CREATING_SINGLE_CERT_RESPONSE;
      goto loser;
    }
    CMMF_CertResponseSetPKIStatusInfoStatus(currResponse, cmmfGranted);
    CMMF_CertResponseSetCertificate(currResponse, issuedCerts[i].cert);
  }
  srv = CMMF_CertRepContentSetCertResponses(certRepContent, responses,
                                       numCerts);
  if (srv != SECSuccess) {
    rv = ERROR_SETTING_CERT_RESPONSES;
    goto loser;
  }
  caList = CERT_NewCertList();
  if (caList == NULL) {
    rv = ERROR_CREATING_CA_LIST;
    goto loser;
  }
  srv = CERT_AddCertToListTail(caList, issuerCert);
  if (srv != SECSuccess) {
    rv = ERROR_ADDING_ISSUER_TO_CA_LIST;
    goto loser;
  }
  srv = CMMF_CertRepContentSetCAPubs(certRepContent, caList);
  CERT_DestroyCertList(caList);
  poolp = PORT_NewArena(1024);
  der = SEC_ASN1EncodeItem(poolp, NULL, certRepContent, 
                        CMMFCertRepContentTemplate);
  if (der == NULL) {
    rv = ERROR_ENCODING_CERT_REP_CONTENT;
    goto loser;
  }
#ifdef WRITE_OUT_RESPONSE
  writeOutItem("CertRepContent.der", der);
#endif
  *base64der = BTOA_DataToAscii(der->data, der->len);
  return NO_ERROR;
 loser:
  return rv;
}

Here is the call graph for this function:

ErrorCode createNewCert ( CERTCertificate **  issuedCert,
CERTCertificateRequest *  oldCertReq,
CRMFCertReqMsg *  currReq,
CRMFCertRequest *  certReq,
CERTCertificate *  issuerCert,
CGIVarTable varTable 
)

Definition at line 382 of file crmfcgi.c.

{
  CERTCertificate *newCert = NULL;
  CERTValidity *validity;
  PRExplodedTime printableTime;
  PRTime now, after;
  ErrorCode rv=NO_ERROR;
  SECKEYPrivateKey *issuerPrivKey;
  SECItem derCert = { 0 };
  SECOidTag signTag;
  SECStatus srv;
  long version;

  now = PR_Now();
  PR_ExplodeTime(now, PR_GMTParameters, &printableTime);
  printableTime.tm_month += 9;
  after = PR_ImplodeTime(&printableTime);
  validity = CERT_CreateValidity(now, after);
  newCert = *issuedCert = 
    CERT_CreateCertificate(rand(), &(issuerCert->subject), validity, 
                        oldCertReq);
  if (newCert == NULL) {
    rv = ERROR_CREATING_NEW_CERTIFICATE;
    goto loser;
  }
  rv = addExtensions(newCert, certReq);
  if (rv != NO_ERROR) {
    goto loser;
  }
  issuerPrivKey = PK11_FindKeyByAnyCert(issuerCert, varTable);
  if (issuerPrivKey == NULL) {
    rv = COULD_NOT_FIND_ISSUER_PRIVATE_KEY;
  }
  switch(issuerPrivKey->keyType) {
  case rsaKey:
    signTag = SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION;
    break;
  case dsaKey:
    signTag = SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST;
    break;
  default:
    rv = UNSUPPORTED_SIGN_OPERATION_FOR_ISSUER;
    goto loser;
  }
  srv = SECOID_SetAlgorithmID(newCert->arena, &newCert->signature, 
                           signTag, 0);
  if (srv != SECSuccess) {
    rv = ERROR_SETTING_SIGN_ALG;
    goto loser;
  }
  srv = CRMF_CertRequestGetCertTemplateVersion(certReq, &version);
  if (srv != SECSuccess) {
    /* No version included in the request */
    *(newCert->version.data) = SEC_CERTIFICATE_VERSION_3;
  } else {
    SECITEM_FreeItem(&newCert->version, PR_FALSE);
    SEC_ASN1EncodeInteger(newCert->arena, &newCert->version, version);
  }
  SEC_ASN1EncodeItem(newCert->arena, &derCert, newCert, 
                   CERT_CertificateTemplate);
  if (derCert.data == NULL) {
    rv = ERROR_ENCODING_NEW_CERT;
    goto loser;
  }
  srv = SEC_DerSignData(newCert->arena, &(newCert->derCert), derCert.data,
                     derCert.len, issuerPrivKey, signTag);
  if (srv != SECSuccess) {
    rv = ERROR_SIGNING_NEW_CERT;
    goto loser;
  }
#ifdef WRITE_OUT_RESPONSE
  writeOutItem("newcert.der", &newCert->derCert);
#endif
  return NO_ERROR;
 loser:
  *issuedCert = NULL;
  if (newCert) {
    CERT_DestroyCertificate(newCert);
  }
  return rv;
                   
}

Here is the call graph for this function:

ErrorCode doChallengeResponse ( CGIVarTable varTable,
CRMFCertReqMsg *  currReq,
CRMFCertRequest *  certReq,
CERTCertificate *  newCert,
ChallengeCreationInfo challs,
int numChall 
)

Definition at line 674 of file crmfcgi.c.

{
  CRMFPOPOPrivKey *privKey = NULL;
  CRMFPOPOPrivKeyChoice privKeyChoice;
  SECStatus srv;
  ErrorCode rv = NO_ERROR;
 
  srv = CRMF_CertReqMsgGetPOPKeyEncipherment(currReq, &privKey);
  if (srv != SECSuccess || privKey == NULL) {
    rv = ERROR_GETTING_KEY_ENCIPHERMENT;
    goto loser;
  } 
  privKeyChoice = CRMF_POPOPrivKeyGetChoice(privKey);
  CRMF_DestroyPOPOPrivKey(privKey);
  switch (privKeyChoice) {
  case crmfSubsequentMessage:
    challs = &challs[*numChall];
    challs->random = rand();
    challs->pubKey = CERT_ExtractPublicKey(newCert);
    if (challs->pubKey == NULL) {
      rv = ERROR_RETRIEVING_PUB_KEY_FOR_CHALL;
      goto loser;
    }
    (*numChall)++;
    rv = DO_CHALLENGE_RESPONSE;
    break;
  case crmfThisMessage:
    /* There'd better be a PKIArchiveControl in this message */
    if (!CRMF_CertRequestIsControlPresent(certReq, 
                                     crmfPKIArchiveOptionsControl)) {
      rv = ERROR_NO_POP_FOR_PRIVKEY;
      goto loser;
    }
    break;
  default:
    rv = ERROR_UNSUPPORTED_POPOPRIVKEY_TYPE;
    goto loser;
  }
loser:
  return rv;
}

Here is the call graph for this function:

ErrorCode doProofOfPossession ( CGIVarTable varTable,
CRMFCertReqMsg *  currReq,
CRMFCertRequest *  certReq,
CERTCertificate *  newCert,
ChallengeCreationInfo challs,
int numChall 
)

Definition at line 719 of file crmfcgi.c.

{
  CRMFPOPChoice popChoice;
  ErrorCode rv = NO_ERROR;

  popChoice = CRMF_CertReqMsgGetPOPType(currReq);
  if (popChoice == crmfNoPOPChoice) {
    rv = NO_POP_FOR_REQUEST;
    goto loser;
  }
  switch (popChoice) {
  case crmfSignature:
    rv = verifySignature(varTable, currReq, certReq, newCert);
    break;
  case crmfKeyEncipherment:
    rv = doChallengeResponse(varTable, currReq, certReq, newCert,
                          challs, numChall);
    break;
  case crmfRAVerified:
  case crmfKeyAgreement:
  default:
    rv = UNSUPPORTED_POP;
    goto loser;
  }
 loser:
  return rv;
}

Here is the call graph for this function:

Definition at line 300 of file crmfcgi.c.

{
  spitOutHeaders();
  printf("<html><head><title>Error</title></head><body><h1>Error processing "
        "data</h1> Received the error %d<p>", errNum);
  if (errNum  ==   REQ_CGI_VAR_NOT_PRESENT) {
    printf ("The missing variable is %s.", missingVar);
  }
  printf ("<i>More useful information here in the future.</i></body></html>");
}

Here is the call graph for this function:

void dumpRequest ( CGIVarTable varTable)

Definition at line 146 of file crmfcgi.c.

{
  int i;
  CGIVariable *var;

  printf ("<table border=1 cellpadding=1 cellspacing=1 width=\"100%%\">\n");
  printf ("<tr><td><b><center>Variable Name<center></b></td>"
          "<td><b><center>Value</center></b></td></tr>\n");
  for (i=0; i<varTable->numVars; i++) {
    var = varTable->variables[i];
    printf ("<tr><td><pre>%s</pre></td><td><pre>%s</pre></td></tr>\n", 
             var->name, var->value);
  }
  printf("</table>\n");
}
void echo_request ( CGIVarTable varTable)

Definition at line 163 of file crmfcgi.c.

{
  spitOutHeaders();
  printf("<html><head><title>CGI Echo Page</title></head>\n"
        "<body><h1>Got the following request</h1>\n");
  dumpRequest(varTable);
  printf("</body></html>");
}

Here is the call graph for this function:

void formatChallenge ( char *  chall64,
char *  certRepContentDER,
ChallengeCreationInfo challInfo,
int  numChalls 
)

Definition at line 764 of file crmfcgi.c.

{
  printf ("function respondToChallenge() {\n"
         "  var chalForm = document.chalForm;\n\n"
         "  chalForm.CertRepContent.value = '");
  convertB64ToJS(certRepContentDER);
  printf ("';\n"
         "  chalForm.ChallResponse.value = crypto.popChallengeResponse('");
  convertB64ToJS(chall64);
  printf("');\n"
        "  chalForm.submit();\n"
        "}\n");

}

Here is the call graph for this function:

void formatCMMFResponse ( char *  nickname,
char *  base64Response 
)

Definition at line 468 of file crmfcgi.c.

{
  char *currLine, *nextLine;

  printf("var retVal = crypto.importUserCertificates(\"%s\",\n", nickname);
  currLine = base64Response;
  while (1) {
    nextLine = strchr(currLine, '\n');
    if (nextLine == NULL) {
      /* print out the last line here. */
      printf ("\"%s\",\n", currLine);
      break;
    }
    nextLine[0] = '\0';
    printf("\"%s\\n\"+\n", currLine);
    currLine = nextLine+1;
  }
  printf("true);\n"
        "if(retVal == '') {\n"
        "\tdocument.write(\"<h1>New Certificate Succesfully Imported.</h1>\");\n"
        "} else {\n"
        "\tdocument.write(\"<h2>Unable to import New Certificate</h2>\");\n"
        "\tdocument.write(\"crypto.importUserCertificates returned <b>\");\n"
        "\tdocument.write(retVal);\n"
        "\tdocument.write(\"</b>\");\n"
        "}\n");
}

Here is the call graph for this function:

char* getNickname ( CERTCertificate *  cert)

Definition at line 510 of file crmfcgi.c.

{
  char *nickname;

  if (cert->nickname != NULL) {
    return cert->nickname;
  }
  nickname = CERT_GetCommonName(&cert->subject);
  if (nickname != NULL) {
    return nickname;
  }
  return CERT_NameToAscii(&cert->subject);
}

Here is the call graph for this function:

ErrorCode initNSS ( CGIVarTable varTable)

Definition at line 274 of file crmfcgi.c.

{
  const char *nssDir;
  PK11SlotInfo *keySlot;
  SECStatus rv;

  nssDir = CGITableFindValue(varTable,"NSSDirectory");
  if (nssDir == NULL) {
    missingVar = "NSSDirectory";
    return REQ_CGI_VAR_NOT_PRESENT;
  }
  rv = NSS_Init(nssDir);
  if (rv != SECSuccess) {
    return NSS_INIT_FAILED;
  }
  PK11_SetPasswordFunc(passwordCallback);
  keySlot = PK11_GetInternalKeySlot();
  rv = PK11_Authenticate(keySlot, PR_FALSE, varTable);
  PK11_FreeSlot(keySlot);
  if (rv != SECSuccess) {
    return AUTH_FAILED;
  }
  return NO_ERROR;
}

Here is the call graph for this function:

ErrorCode initOldCertReq ( CERTCertificateRequest *  oldCertReq,
CERTName *  subject,
CERTSubjectPublicKeyInfo *  spki 
)

Definition at line 312 of file crmfcgi.c.

{
  PRArenaPool *poolp;

  poolp = oldCertReq->arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
  SEC_ASN1EncodeInteger(poolp, &oldCertReq->version, 
                     SEC_CERTIFICATE_VERSION_3);
  CERT_CopyName(poolp, &oldCertReq->subject, subject);
  SECKEY_CopySubjectPublicKeyInfo(poolp, &oldCertReq->subjectPublicKeyInfo,
                              spki);
  oldCertReq->attributes = NULL;
  return NO_ERROR;
}

Here is the call graph for this function:

ErrorCode issueCerts ( CertResponseInfo issuedCerts,
int  numCerts,
CERTCertificate *  issuerCert 
)

Definition at line 592 of file crmfcgi.c.

{
  ErrorCode rv;
  char *base64Response;

  rv = createCMMFResponse(issuedCerts, numCerts, issuerCert, &base64Response);
  if (rv != NO_ERROR) {
    goto loser;
  }
  spitOutCMMFResponse(getNickname(issuedCerts[0].cert),base64Response);
  return NO_ERROR;
 loser:
  return rv;
}

Here is the call graph for this function:

ErrorCode issueChallenge ( CertResponseInfo issuedCerts,
int  numCerts,
ChallengeCreationInfo challInfo,
int  numChalls,
CERTCertificate *  issuer,
CGIVarTable varTable 
)

Definition at line 815 of file crmfcgi.c.

{
  ErrorCode rv = NO_ERROR;
  CMMFPOPODecKeyChallContent *chalContent = NULL;
  int i;
  SECStatus srv;
  PRArenaPool *poolp;
  CERTGeneralName *genName;
  SECItem *challDER = NULL;
  char *chall64, *certRepContentDER;

  rv = createCMMFResponse(issuedCerts, numCerts, issuer, 
                       &certRepContentDER);
  if (rv != NO_ERROR) {
    goto loser;
  }
  chalContent = CMMF_CreatePOPODecKeyChallContent();
  if (chalContent == NULL) {
    rv = ERROR_CREATING_EMPTY_CHAL_CONTENT;
    goto loser;
  }
  poolp = PORT_NewArena(1024);
  if (poolp == NULL) {
    rv = OUT_OF_MEMORY;
    goto loser;
  }
  genName = CERT_GetCertificateNames(issuer, poolp);
  if (genName == NULL) {
    rv = ERROR_EXTRACTING_GEN_NAME_FROM_ISSUER;
    goto loser;
  }
  for (i=0;i<numChalls;i++) {
    srv = CMMF_POPODecKeyChallContentSetNextChallenge(chalContent,
                                                challInfo[i].random,
                                                genName,
                                                challInfo[i].pubKey,
                                                varTable);
    SECKEY_DestroyPublicKey(challInfo[i].pubKey);
    if (srv != SECSuccess) {
      rv = ERROR_SETTING_CHALLENGE;
      goto loser;
    }
  }
  challDER = SEC_ASN1EncodeItem(NULL, NULL, chalContent, 
                            CMMFPOPODecKeyChallContentTemplate);
  if (challDER == NULL) {
    rv = ERROR_ENCODING_CHALL;
    goto loser;
  }
  chall64 = BTOA_DataToAscii(challDER->data, challDER->len);
  SECITEM_FreeItem(challDER, PR_TRUE);
  if (chall64 == NULL) {
    rv = ERROR_CONVERTING_CHALL_TO_BASE64;
    goto loser;
  }
  spitOutChallenge(chall64, certRepContentDER, challInfo, numChalls,
                 getNickname(issuedCerts[0].cert));
 loser:
  return rv;
}

Here is the call graph for this function:

int main ( void  )

main()

Definition at line 1076 of file crmfcgi.c.

{
  char *form_output = NULL;
  int   form_output_len, form_output_used;
  CGIVarTable varTable = { 0 };
  ErrorCode errNum = 0;
  char *certRepContent;

#ifdef ATTACH_CGI
  /* Put an ifinite loop in here so I can attach to 
   * the process after the process is spun off
   */
  { int stupid = 1;
    while (stupid);
  }
#endif

  form_output_used = 0;
  srand(time(NULL));
  while (feof(stdin) == 0) {
    if (form_output == NULL) {
      form_output = PORT_NewArray(char, DEFAULT_ALLOC_SIZE+1);
      form_output_len  = DEFAULT_ALLOC_SIZE;
    } else if ((form_output_used + DEFAULT_ALLOC_SIZE) >= form_output_len) {
      form_output_len += DEFAULT_ALLOC_SIZE;
      form_output = PORT_Realloc(form_output, form_output_len+1);
    }
    form_output_used += fread(&form_output[form_output_used], sizeof(char), 
                           DEFAULT_ALLOC_SIZE, stdin);
  }
  ParseInputVariables(&varTable, form_output);
  certRepContent = CGITableFindValue(&varTable, "CertRepContent");
  if (certRepContent == NULL) {
    errNum = initNSS(&varTable);
    if (errNum != 0) {
      goto loser;
    }
    errNum = processRequest(&varTable);
  } else {
    errNum = processChallengeResponse(&varTable, certRepContent);
  }
  if (errNum != NO_ERROR) {
    goto loser;
  }
  goto done;
loser:
  dumpErrorMessage(errNum);
done:
  free (form_output);
  return 0;
}

Here is the call graph for this function:

void ParseInputVariables ( CGIVarTable varTable,
char *  form_output 
)

Definition at line 234 of file crmfcgi.c.

{
  varTable->variables = malloc(sizeof(CGIVariable*)*DEFAULT_CGI_VARS);
  varTable->numVars = 0;
  varTable->numAlloc = DEFAULT_CGI_VARS;
  while (form_output && form_output[0] != '\0') {
    form_output = parseNextVariable(varTable, form_output);
  }
}

Here is the call graph for this function:

char* parseNextVariable ( CGIVarTable varTable,
char *  form_output 
)

Definition at line 198 of file crmfcgi.c.

{
  char *ampersand, *equal;
  CGIVariable *var;

  if (varTable->numVars == varTable->numAlloc) {
    CGIVariable **newArr = realloc(varTable->variables, 
                                   (varTable->numAlloc + DEFAULT_CGI_VARS)*sizeof(CGIVariable*));
    if (newArr == NULL) {
      return NULL;
    }
    varTable->variables = newArr;
    varTable->numAlloc += DEFAULT_CGI_VARS;
  }
  equal     = strchr(form_output, '=');
  if (equal == NULL) {
    return NULL;
  }
  ampersand = strchr(equal, '&');
  if (ampersand == NULL) {
    return NULL;
  }
  equal[0] = '\0';
  if (ampersand != NULL) {
    ampersand[0] = '\0';
  }
  var = malloc(sizeof(CGIVariable));
  var->name = form_output; 
  var->value = &equal[1];
  varTable->variables[varTable->numVars] = var;
  varTable->numVars++;
  processVariable(var);
  return (ampersand != NULL) ? &ampersand[1] : NULL;
}

Here is the call graph for this function:

char* passwordCallback ( PK11SlotInfo *  slot,
PRBool  retry,
void arg 
)

Definition at line 260 of file crmfcgi.c.

{
  const char *passwd;
  if (retry) {
    return NULL;
  }
  passwd = CGITableFindValue((CGIVarTable*)arg, "dbPassword");
  if (passwd == NULL) {
    return NULL;
  }
  return PORT_Strdup(passwd);
}

Here is the call graph for this function:

ErrorCode processChallengeResponse ( CGIVarTable varTable,
const char *  certRepContent 
)

Definition at line 1003 of file crmfcgi.c.

{
  SECItem binDER = { 0 };
  SECStatus srv;
  ErrorCode rv = NO_ERROR;
  const char *clientResponse;
  const char *formChalValue;
  const char *nickname;
  CMMFPOPODecKeyRespContent *respContent = NULL;
  int numResponses,i;
  long curResponse, expectedResponse;
  char cgiChalVar[10];
#ifdef WRITE_OUT_RESPONSE
  SECItem certRepBinDER = { 0 };

  ATOB_ConvertAsciiToItem(&certRepBinDER, certRepContent);
  writeOutItem("challCertRepContent.der", &certRepBinDER);
  PORT_Free(certRepBinDER.data);
#endif  
  clientResponse = CGITableFindValue(varTable, "ChallResponse");
  if (clientResponse == NULL) {
    rv =   REQ_CGI_VAR_NOT_PRESENT;
    missingVar = "ChallResponse";
    goto loser;
  }
  srv = ATOB_ConvertAsciiToItem(&binDER, clientResponse);
  if (srv != SECSuccess) {
    rv = ERROR_CONVERTING_RESP_FROM_CHALL_TO_BIN;
    goto loser;
  }
  respContent = CMMF_CreatePOPODecKeyRespContentFromDER(binDER.data,
                                                 binDER.len);
  SECITEM_FreeItem(&binDER, PR_FALSE);
  binDER.data = NULL;
  if (respContent == NULL) {
    rv = ERROR_CREATING_KEY_RESP_FROM_DER;
    goto loser;
  }
  numResponses = CMMF_POPODecKeyRespContentGetNumResponses(respContent);
  for (i=0;i<numResponses;i++){
    srv = CMMF_POPODecKeyRespContentGetResponse(respContent,i,&curResponse);
    if (srv != SECSuccess) {
      rv = ERROR_RETRIEVING_CLIENT_RESPONSE_TO_CHALLENGE;
      goto loser;
    }
    sprintf(cgiChalVar, "chal%d", i+1);
    formChalValue = CGITableFindValue(varTable, cgiChalVar);
    if (formChalValue == NULL) {
      rv = REQ_CGI_VAR_NOT_PRESENT;
      missingVar = strdup(cgiChalVar);
      goto loser;
    }
    sscanf(formChalValue, "%ld", &expectedResponse);
    if (expectedResponse != curResponse) {
      rv = ERROR_RETURNED_CHALL_NOT_VALUE_EXPECTED;
      goto loser;
    }
  }
  nickname = CGITableFindValue(varTable, "nickname");
  if (nickname == NULL) {
    rv = REQ_CGI_VAR_NOT_PRESENT;
    missingVar = "nickname";
    goto loser;
  }
  spitOutCMMFResponse(nickname, certRepContent);
 loser:
  if (respContent != NULL) {
    CMMF_DestroyPOPODecKeyRespContent(respContent);
  }
  return rv;
}

Here is the call graph for this function:

Definition at line 880 of file crmfcgi.c.

{
  CERTCertDBHandle *certdb;
  SECKEYKeyDBHandle *keydb;
  CRMFCertReqMessages *certReqs = NULL;
  const char *crmfReq;
  const char *caNickname;
  CERTCertificate *caCert = NULL;
  CertResponseInfo *issuedCerts = NULL;
  CERTSubjectPublicKeyInfo spki = { 0 };
  ErrorCode rv=NO_ERROR;
  PRBool doChallengeResponse = PR_FALSE;
  SECItem der = { 0 };
  SECStatus srv;
  CERTCertificateRequest oldCertReq = { 0 };
  CRMFCertReqMsg **reqMsgs = NULL,*currReq = NULL;
  CRMFCertRequest **reqs = NULL, *certReq = NULL;
  CERTName         subject = { 0 };
  int numReqs,i;
  ChallengeCreationInfo *challInfo=NULL;
  int numChalls = 0;

  certdb = CERT_GetDefaultCertDB();
  keydb = SECKEY_GetDefaultKeyDB();
  crmfReq = CGITableFindValue(varTable, "CRMFRequest");
  if (crmfReq == NULL) {
    rv = CGI_VAR_MISSING;
    missingVar = "CRMFRequest";
    goto loser;
  }
  caNickname = CGITableFindValue(varTable, "CANickname");
  if (caNickname == NULL) {
    rv = CGI_VAR_MISSING;
    missingVar = "CANickname";
    goto loser;
  }
  caCert = CERT_FindCertByNickname(certdb, caNickname);
  if (caCert == NULL) {
    rv = COULD_NOT_FIND_CA;
    goto loser;
  }
  srv = ATOB_ConvertAsciiToItem(&der, crmfReq);
  if (srv != SECSuccess) {
    rv = BAD_ASCII_FOR_REQ;
    goto loser;
  }
  certReqs = CRMF_CreateCertReqMessagesFromDER(der.data, der.len);
  SECITEM_FreeItem(&der, PR_FALSE);
  if (certReqs == NULL) {
    rv = COULD_NOT_DECODE_REQS;
    goto loser;
  }
  numReqs = CRMF_CertReqMessagesGetNumMessages(certReqs);
  issuedCerts = PORT_ZNewArray(CertResponseInfo, numReqs);
  challInfo   = PORT_ZNewArray(ChallengeCreationInfo, numReqs);
  if (issuedCerts == NULL || challInfo == NULL) {
    rv = OUT_OF_MEMORY;
    goto loser;
  }
  reqMsgs = PORT_ZNewArray(CRMFCertReqMsg*,   numReqs);
  reqs    = PORT_ZNewArray(CRMFCertRequest*, numReqs);
  if (reqMsgs == NULL || reqs == NULL) {
    rv =   OUT_OF_MEMORY;
    goto loser;
  }
  for (i=0; i<numReqs; i++) {
    currReq = reqMsgs[i] = 
      CRMF_CertReqMessagesGetCertReqMsgAtIndex(certReqs, i);
    if (currReq == NULL) {
      rv = ERROR_RETRIEVING_REQUEST_MSG;
      goto loser;
    }
    certReq = reqs[i] = CRMF_CertReqMsgGetCertRequest(currReq);
    if (certReq == NULL) {
      rv = ERROR_RETRIEVING_CERT_REQUEST;
      goto loser;
    }
    srv = CRMF_CertRequestGetCertTemplateSubject(certReq, &subject);
    if (srv != SECSuccess) {
      rv = ERROR_RETRIEVING_SUBJECT_FROM_REQ;
      goto loser;
    }
    srv = CRMF_CertRequestGetCertTemplatePublicKey(certReq, &spki);
    if (srv != SECSuccess) {
      rv = ERROR_RETRIEVING_PUBLIC_KEY_FROM_REQ;
      goto loser;
    }
    rv = initOldCertReq(&oldCertReq, &subject, &spki);
    if (rv != NO_ERROR) {
      goto loser;
    }
    rv = createNewCert(&issuedCerts[i].cert, &oldCertReq, currReq, certReq, 
                     caCert, varTable);
    if (rv != NO_ERROR) {
      goto loser;
    }
    rv = doProofOfPossession(varTable, currReq, certReq, issuedCerts[i].cert,
                          challInfo, &numChalls);
    if (rv != NO_ERROR) {
      if (rv == DO_CHALLENGE_RESPONSE) {
       doChallengeResponse = PR_TRUE;
      } else {
       goto loser;
      }
    }
    CRMF_CertReqMsgGetID(currReq, &issuedCerts[i].certReqID);
    CRMF_DestroyCertReqMsg(currReq);
    CRMF_DestroyCertRequest(certReq);
  }
  if (doChallengeResponse) {
    rv = issueChallenge(issuedCerts, numReqs, challInfo, numChalls, caCert,
                     varTable);
  } else {
    rv = issueCerts(issuedCerts, numReqs, caCert);
  }
 loser:
  if (certReqs != NULL) {
    CRMF_DestroyCertReqMessages(certReqs);
  }
  return rv;
}

Here is the call graph for this function:

Definition at line 173 of file crmfcgi.c.

{
  char *plusSign, *percentSign;

  /*First look for all of the '+' and convert them to spaces */
  plusSign = var->value;
  while ((plusSign=strchr(plusSign, '+')) != NULL) {
    *plusSign = ' ';
  }
  percentSign = var->value;
  while ((percentSign=strchr(percentSign, '%')) != NULL) {
    char string[3];
    int  value;

    string[0] = percentSign[1];
    string[1] = percentSign[2];
    string[2] = '\0';

    sscanf(string,"%x", &value);
    *percentSign = (char)value;
    memmove(&percentSign[1], &percentSign[3], 1+strlen(&percentSign[3]));
  }
}

Here is the call graph for this function:

void spitOutChallenge ( char *  chall64,
char *  certRepContentDER,
ChallengeCreationInfo challInfo,
int  numChalls,
char *  nickname 
)

Definition at line 781 of file crmfcgi.c.

{
  int i;

  spitOutHeaders();
  printf("<html>\n"
        "<head>\n"
        "<title>Challenge Page</title>\n"
        "<script language=\"JavaScript\">\n"
        "<!--\n");
  /* The JavaScript function actually gets defined within
   * this function call
   */
  formatChallenge(chall64, certRepContentDER, challInfo, numChalls);
  printf("// -->\n"
        "</script>\n"
        "</head>\n"
        "<body onLoad='respondToChallenge()'>\n"
        "<h1>Cartman is now responding to the Challenge "
        "presented by the CGI</h1>\n"
        "<form action='crmfcgi' method='post' name='chalForm'>\n"
        "<input type='hidden' name=CertRepContent value=''>\n"
        "<input type='hidden' name=ChallResponse value=''>\n");
  for (i=0;i<numChalls; i++) {
    printf("<input type='hidden' name='chal%d' value='%d'>\n",
          i+1, challInfo[i].random);
  }
  printf("<input type='hidden' name='nickname' value='%s'>\n", nickname);
  printf("</form>\n</body>\n</html>");
}

Here is the call graph for this function:

void spitOutCMMFResponse ( char *  nickname,
char *  base64Response 
)

Definition at line 497 of file crmfcgi.c.

{
  spitOutHeaders();
  printf("<html>\n<head>\n<title>CMMF Resonse Page</title>\n</head>\n\n"
        "<body><h1>CMMF Response Page</h1>\n"
        "<script language=\"JavaScript\">\n"
        "<!--\n");
  formatCMMFResponse(nickname, base64Response);
  printf("// -->\n"
        "</script>\n</body>\n</html>");
}

Here is the call graph for this function:

Definition at line 140 of file crmfcgi.c.

{
  printf("Content-type: text/html\n\n");
}
ErrorCode verifySignature ( CGIVarTable varTable,
CRMFCertReqMsg *  currReq,
CRMFCertRequest *  certReq,
CERTCertificate *  newCert 
)

Definition at line 609 of file crmfcgi.c.

{
  SECStatus srv;
  ErrorCode rv = NO_ERROR;
  CRMFPOPOSigningKey *signKey   = NULL;
  SECAlgorithmID     *algID     = NULL;
  SECItem            *signature = NULL;
  SECKEYPublicKey    *pubKey    = NULL;
  SECItem            *reqDER    = NULL;

  srv = CRMF_CertReqMsgGetPOPOSigningKey(currReq, &signKey);
  if (srv != SECSuccess || signKey == NULL) {
    rv = ERROR_RETRIEVING_POP_SIGN_KEY;
    goto loser;
  }
  algID = CRMF_POPOSigningKeyGetAlgID(signKey);
  if (algID == NULL) {
    rv = ERROR_RETRIEVING_ALG_ID_FROM_SIGN_KEY;
    goto loser;
  }
  signature = CRMF_POPOSigningKeyGetSignature(signKey);
  if (signature == NULL) {
    rv = ERROR_RETRIEVING_SIGNATURE_FROM_POP_SIGN_KEY;
    goto loser;
  }
  /* Make the length the number of bytes instead of bits */
  signature->len = (signature->len+7)/8;
  pubKey = CERT_ExtractPublicKey(newCert);
  if (pubKey == NULL) {
    rv = ERROR_RETRIEVING_PUB_KEY_FROM_NEW_CERT;
    goto loser;
  }
  reqDER = SEC_ASN1EncodeItem(NULL, NULL, certReq, CRMFCertRequestTemplate);
  if (reqDER == NULL) {
    rv = ERROR_ENCODING_CERT_REQ_FOR_POP;
    goto loser;
  }
  srv = VFY_VerifyData(reqDER->data, reqDER->len, pubKey, signature,
                     SECOID_FindOIDTag(&algID->algorithm), varTable);
  if (srv != SECSuccess) {
    rv = ERROR_VERIFYING_SIGNATURE_POP;
    goto loser;
  }
  /* Fall thru in successfull case. */
 loser:
  if (pubKey != NULL) {
    SECKEY_DestroyPublicKey(pubKey);
  }
  if (reqDER != NULL) {
    SECITEM_FreeItem(reqDER, PR_TRUE);
  }
  if (signature != NULL) {
    SECITEM_FreeItem(signature, PR_TRUE);
  }
  if (algID != NULL) {
    SECOID_DestroyAlgorithmID(algID, PR_TRUE);
  }
  if (signKey != NULL) {
    CRMF_DestroyPOPOSigningKey(signKey);
  }  
  return rv;
}

Here is the call graph for this function:

void writeOutItem ( const char *  filePath,
SECItem *  der 
)

Definition at line 369 of file crmfcgi.c.

{
  PRFileDesc *outfile;

  outfile = PR_Open (filePath,
                   PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE,
                   0666);
  PR_Write(outfile, der->data, der->len);
  PR_Close(outfile);

}

Variable Documentation

char* missingVar = NULL

Definition at line 76 of file crmfcgi.c.