crmfcgi.c

来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 1,124 行 · 第 1/2 页

C
1,124
字号
  }  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;}ErrorCodeissueCerts(CertResponseInfo *issuedCerts, int numCerts, 	   CERTCertificate *issuerCert){  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;}ErrorCodeverifySignature(CGIVarTable *varTable, CRMFCertReqMsg *currReq, 		CRMFCertRequest *certReq, CERTCertificate *newCert){  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;}ErrorCodedoChallengeResponse(CGIVarTable *varTable, CRMFCertReqMsg *currReq, 		    CRMFCertRequest *certReq, CERTCertificate *newCert,		    ChallengeCreationInfo *challs, int *numChall){  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;}ErrorCodedoProofOfPossession(CGIVarTable *varTable, CRMFCertReqMsg *currReq, 		    CRMFCertRequest *certReq, CERTCertificate *newCert,		    ChallengeCreationInfo *challs, int *numChall){  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;}voidconvertB64ToJS(char *base64){  int i;  for (i=0; base64[i] != '\0'; i++) {    if (base64[i] == '\n') {      printf ("\\n");    }else {      printf ("%c", base64[i]);    }  }}voidformatChallenge(char *chall64, char *certRepContentDER,		 ChallengeCreationInfo *challInfo, int numChalls){  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");}voidspitOutChallenge(char *chall64, char *certRepContentDER,		 ChallengeCreationInfo *challInfo, int numChalls,		 char *nickname){  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>");}ErrorCodeissueChallenge(CertResponseInfo *issuedCerts, int numCerts, 	       ChallengeCreationInfo *challInfo, int numChalls,	       CERTCertificate *issuer, CGIVarTable *varTable){  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;}ErrorCodeprocessRequest(CGIVarTable *varTable){  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;}ErrorCodeprocessChallengeResponse(CGIVarTable *varTable, const char *certRepContent){  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;}intmain(){  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;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?