/* ***************************************************************** *
 * Copyright 1998 International Business Machines Corporation. All   *
 * Rights Reserved.                                                  *
 *                                                                   *
 * Please read this carefully.  Your use of this reference           *
 * implementation of certain of the IETF public-key infrastructure   *
 * specifications ("Software") indicates your acceptance of the      *
 * following.  If you do not agree to the following, do not install  *
 * or use any of the Software.                                       *
 *                                                                   *
 * Permission to use, reproduce, distribute and create derivative    *
 * works from the Software ("Software Derivative Works"), and to     *
 * distribute such Software Derivative Works is hereby granted to    *
 * you by International Business Machines Corporation ("IBM").  This *
 * permission includes a license under the patents of IBM that are   *
 * necessarily infringed by your use of the Software as provided by  *
 * IBM.                                                              *
 *                                                                   *
 * IBM licenses the Software to you on an "AS IS" basis, without     *
 * warranty of any kind.  IBM HEREBY EXPRESSLY DISCLAIMS ALL         *
 * WARRANTIES OR CONDITIONS, EITHER EXPRESS OR IMPLIED, INCLUDING,   *
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OR CONDITIONS OF       *
 * MERCHANTABILITY, NON INFRINGEMENT AND FITNESS FOR A PARTICULAR    *
 * PURPOSE.  You are solely responsible for determining the          *
 * appropriateness of using this Software and assume all risks       *
 * associated with the use of this Software, including but not       *
 * limited to the risks of program errors, damage to or loss of      *
 * data, programs or equipment, and unavailability or interruption   *
 * of operations.                                                    *
 *                                                                   *
 * IBM WILL NOT BE LIABLE FOR ANY DIRECT DAMAGES OR FOR ANY SPECIAL, *
 * INCIDENTAL, OR  INDIRECT DAMAGES OR FOR ANY ECONOMIC              *
 * CONSEQUENTIAL DAMAGES (INCLUDING LOST PROFITS OR SAVINGS), EVEN   *
 * IF IBM HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.  IBM  *
 * will not be liable for the loss of, or damage to, your records or *
 * data, or any damages claimed by you based on a third party claim. *
 *                                                                   *
 * IBM wishes to obtain your feedback to assist in improving the     *
 * Software.  You grant IBM a world-wide, royalty-free right to use, *
 * copy, distribute, sublicense and prepare derivative works based   *
 * upon any feedback, including materials, error corrections,        *
 * Software Derivatives, enhancements, suggestions and the like that *
 * you provide to IBM relating to the Software (this does not        *
 * include products for which you charge a royalty and distribute to *
 * IBM under other terms and conditions).                            *
 *                                                                   *
 * You agree to distribute the Software and any Software Derivatives *
 * under a license agreement that: 1) is sufficient to notify all    *
 * licensees of the Software and Software Derivatives that IBM       *
 * assumes no liability for any claim that may arise regarding the   *
 * Software or Software Derivatives, and 2) that disclaims all       *
 * warranties, both express and implied, from IBM regarding the      *
 * Software and Software Derivatives.  (If you include this          *
 * Agreement with any distribution of the Software or Software       *
 * Derivatives you will have met this requirement.)  You agree that  *
 * you will not delete any copyright notices in the Software.        *
 *                                                                   *
 * This Agreement is the exclusive statement of your rights in the   *
 * Software as provided by IBM.   Except for the rights granted to   *
 * you in the second paragraph above, You are not granted any other  *
 * patent rights, including but not limited to the right to make     *
 * combinations of the Software with products that infringe IBM      *
 * patents. You agree to comply with all applicable laws and         *
 * regulations, including all export and import laws and regulation. *
 * This Agreement is governed by the laws of the State of New York.  *
 * This Agreement supersedes all other communications,               *
 * understandings or agreements we may have had prior to this        *
 * Agreement.                                                        *
 * ***************************************************************** */

#include <jonah.h>
#include <init.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ObjectStore.h>
#include <ObjectDefs.h>
#include <JonahOst.h>
#include <asn1msg.h>
#include <apimsg.h>
#include <JonahMsg.h> 
#include <BinBinInit.h>

// #define TRY_TO_CLEAR_CACHE
#define NEWTESTLOCKING
#define PEM(status_number) \
{ Jonah_sprintMsg(ErrorMessage,ErrorMessageSize, \
	              status_number,"Unknown Message"); \
  printf("Trouble at %d with %d: %s\n",__LINE__, status_number,ErrorMessage); \
  fflush(stdout);}
	    
#define PRINTTESTRESULT(psuccess,pthistest) {\
if (psuccess)\
   {\
   printf("Test %d, %s, was successful\n",pthistest,testname[pthistest]);\
   }\
else\
   {\
   printf("FAILED TEST %d,rc=%d, %s!\n",pthistest,rc,testname[pthistest]);\
   PEM(rc); \
   lastfailure=thistest;\
   numfailure++;\
   }\
fflush(stdout);\
thistest++;\
}

void
notify(uint32 id, uint32 status)
{
		fprintf(stderr, "Notify: ID=%d\tSTATUS=%x\n", id, status);
		return;
}


void print_subject_key_alg(octetString algorithm)
{
asn_oid alg_oid;
uint32 status;
buffer_t buf1,buf2;

buf1.data=algorithm.data;
buf1.data_len=algorithm.length;
status=alg_oid.set_value(algorithm.data,algorithm.length);
if (status==0) status=alg_oid.display_printable(buf2);
else 
	{
	printf("alg_oid.set_value failed, status=%d.\n",status);
	fflush(stdout);
	return;
	}
if (status==0) 
	{
	printf("OID=%.*s\n",buf2.data_len,buf2.data);
	fflush(stdout);
	}
else
	{
	printf("alg_oid.display_printable failed, status=%d.\n",status);
	fflush(stdout);
	}

return;
}

// HackSerial is a routine to set the serial number in a cert req
// It is only called in the middle of a long series of  test,
// so the reqId is already locked
void HackSerial(uint32 reqId, uint32 newserial)
{
ObjStoreData		*objsPtr = NULL;
uint32			objClass;
uint32			status;
CertReqMsg		*certreqmsg = NULL;

status=JnhGetObjectModify(reqId,&objClass,&objsPtr);
if ( objClass | ObjClTypeCert )
	{
	fflush(stdout);printf("Object %d has ObjClTypeCert.\n",reqId);
	}


if ( objsPtr->msg.value.selected()== OBJ_MSG_CERTREQ )
	{
	certreqmsg=objsPtr->msg.value.certreq.value.get_child(0);
	}
else if ( objsPtr->msg.value.selected()== OBJ_MSG_IREQ )
	{
	certreqmsg=objsPtr->msg.value.ireq.value.get_child(0);
	}
else
	{
	fflush(stdout);printf("This was not a Certficate request message.\n");
	}

if (certreqmsg==NULL)
	{
	fflush(stdout);printf("Could not get CertReq.\n");
	}
else
	{

	status=certreqmsg->certReq.certTemplate.serialNumber.
		value.set_value(newserial);
	if(status==0){
	   fflush(stdout);printf("serialNumber=%d was set.\n",newserial);
	   }
	else
	   {
	   fflush(stdout);printf("Failed setting serial number, rc=%d.\n",
	                         status);
	   }

	fflush(stdout);
	}

return;
}



#define RSUBJECT (utf8String) "/CN=A_User"
#define SSUBJECT (utf8String) "/OU=Company/CN=S_User"
#define RISSUER  (utf8String) "/C=US"
#define SISSUER  (utf8String) "/C=UK"
#define SSERIAL  327

int main(int argc, char * argv[])
{
char * parm1=NULL, * parm2=NULL, * parm3=NULL;
int rc=0;
int lastfailure=0;
int numfailure=0;
int thistest=0;
int success=1;
char * testname[200];
ObjStoreData		*objsPtr = NULL;
uint32			objClass;
#define EMS 100 // ErrorMessage Buffer Size
int ErrorMessageSize=EMS;
char ErrorMessage[EMS];


// parameters for testing

          uint32 maxPathLen=0;
          uint32 numberConstraints=0;
          uint32 numberExtensions=0;
          uint32 numberMappings=0;
          uint32 numberNotices=0;
          uint32 numberPolicies=0;
          uint32 numberSubtrees=0;
          uint32 numberUsages=0;
          uint32 status=0;
          uint32 ** maxLengths=NULL;
          uint32 ** minLenths=NULL;
          uint32 keyId=0;
          uint32 maxLength=0;
          uint32 minLength=0;
          uint32 *notices=NULL;
          uint32 reqId=0;
          uint32 repId=0;
          uint32 prgId=0;
          uint32 i_usage=0;


          IBOOL keyPresent=NULL;
          IBOOL critical=0;
          IBOOL inhibitMapping=0;
          IBOOL isCaCert=0;
          IBOOL requireExplicitPolicy=0;

          IBOOL * requireExplicitPolicys=NULL;
          IBOOL * inhibitMappings=NULL;
          IBOOL * criticals=NULL;

          keyUsage_t  keyUsage;
	  keyUsage_t  usages;

          octetString extId;
          octetString issuerDomainPolicy;
          octetString o_keyId;
          octetString policy;
          octetString policyId;
          octetString serialNumber;
          octetString subjectDomainPolicy;
          octetString usage;
          octetString value;
          utf8String CPS_URI;
          utf8String authorityName;
          utf8String base;
          utf8String explicitText;
          utf8String issuer;
          utf8String organization;
          utf8String subject;
          octetString algorithm;
          octetString * key;
          octetString * policyQualifierId;
          octetString * subjectKeyId;
          octetString ** extensions;
          octetString ** issuerDomainPolicies;
          octetString ** subjectDomainPolicies;
          octetString ** policies=NULL;
          octetString ** o_usages=NULL;
          octetString ** values=NULL;
          utf8String ** bases=NULL;
	  utf8String  PreRegistrationRecord;
          utcDateTime endDate;
          utcDateTime startDate;
          utcDateTime notBefore;
          utcDateTime notAfter;

// rename parm1, parm2, and parm3 as appropriate
if (argc > 1) parm1=argv[1];
else parm1="other";
if (argc > 2) parm2=argv[2];
else parm2="999";
if (argc > 3) parm3=argv[3];

thistest=1;
// Set up for testing.  We will claim to be CA for most generality
//

status=JNH_register_callback(&notify);
if ( status != 0 ) 
{
	PEM(status);
	exit(status);
}

// status=BinInit();
if (status != 0 )
{
	PEM(status);
//	exit(status);
}


status=JNH_start_server(Init_CA);
if ( status != 0 ) 
{
	PEM(status);
//	exit(status);
}

status = JNH_server_login_pwd((utf8String) "foo");
if ( status != 0 ) 
{
	PEM(status);
//	exit(status);
}


if ( strcmp(parm1,"check") == 0 )
{
reqId=atoi(parm2);
status=JNH_reserve_object(reqId);

rc=JNH_inquire_certreq_enddate
         (reqId, &endDate);

printf("inquire_certreq_endate(%d)=%d.\n",reqId,rc);
printf("Date=%d/%d/%d, %d:%d:%d\n",
endDate.year,
endDate.month,
endDate.day,
endDate.hour,
endDate.min,
endDate.sec);

rc=JNH_inquire_certreq_subject
         (reqId, &subject);
printf("inquire_certreq_subject(%d)=%d.\n",reqId,rc);
if ( subject==NULL) printf("subject=(null)\n");
else printf("Subject Name=%s.\n",subject);

status=JNH_release_object(reqId);

return 0;
}
else
{
// Preregister the user
status = JNH_RA_preregister_user(
		RISSUER,
		RSUBJECT,
		0, // expire in zero seconds
		(utf8String) "ra_pw",
		& PreRegistrationRecord);
if ( status != 0 ) 
{
	PEM(status);
//	exit(status);
}
printf("PreRegistrationRecord=\"%s\"\n",PreRegistrationRecord);

// Make a Certficate Request
status = JNH_preregister_user(PreRegistrationRecord,
	(utf8String) "user_pw",
	&reqId);
printf("JNH_preregister_user rc=%d,Request ID is %d.\n",status,reqId);

#ifdef TRY_TO_CLEAR_CACHE
// L TODO - revise the Jnh calls below to get a lock
#ifdef NEWTESTLOCKING
status=JnhLockObject(reqId);
#endif /* NEWTESTLOCKING */
status=JnhGetObjectModify(reqId,&objClass,&objsPtr);
status = JnhSynchObject(reqId);
printf("JnhSynchObject rc=%d, Request ID=%d.\n",status,reqId);
#endif /* TRY_TO_CLEAR_CACHE */

// HACK - prgId is always one less than reqID for this test program
prgId=reqId-1;

// Make a Certficate Request, then make it into a certificate reply
status = JNH_preregister_user(PreRegistrationRecord,
	(utf8String) "user_pw",
	&repId);
printf("JNH_preregister_user rc=%d,Reply ID is %d.\n",status,repId);
status = JNH_create_certificate(repId,0);
printf("JNH_create_certificate rc=%d, Reply ID=%d.\n",status,repId);

#ifdef TRY_TO_CLEAR_CACHE
#ifdef NEWTESTLOCKING
status=JnhLockObject(repId);
#endif /* NEWTESTLOCKING */

status=JnhGetObjectModify(repId,&objClass,&objsPtr);

status = JnhUnlockObject(repId);
printf("JnhUnlockObject rc=%d, Reply ID=%d.\n",status,repId);
#endif /* TRY_TO_CLEAR_CACHE */

printf("Start Tests.\n");fflush(stdout);
// Get locks on the IDs
status=JNH_reserve_object(reqId);
status=JNH_reserve_object(repId);


testname[thistest]="JNH_inquire_certreq_subject";
rc=JNH_inquire_certreq_subject
         (reqId, &subject);

success=(  (rc==0)
         &&(strcmp((const char *) subject,(const char *)RSUBJECT)==0)
        );
PRINTTESTRESULT(success,thistest);
if (success) printf("Subject Name was %s.\n",subject);

testname[thistest]="JNH_set_certreq_subject";
rc=JNH_set_certreq_subject
         (reqId, SSUBJECT);

success=(rc==0);
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_inquire_certreq_subject";
rc=JNH_inquire_certreq_subject
         (reqId, &subject);

success=(  (rc==0)
         &&(strcmp((const char *) subject,(const char *)SSUBJECT)==0)
        );
PRINTTESTRESULT(success,thistest);
if (success) printf("Subject Name was %s.\n",subject);

testname[thistest]="JNH_inquire_certreq_issuer";
rc=JNH_inquire_certreq_issuer
         (reqId, &issuer);

success=(  (rc==0)
         &&(strcmp((const char *) issuer,(const char *)RISSUER)==0)
        );
PRINTTESTRESULT(success,thistest);
if (success) printf("Issuer Name was %s.\n",issuer);

testname[thistest]="JNH_set_certreq_issuer";
rc=JNH_set_certreq_issuer
         (reqId, SISSUER);

success=(rc==0);
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_inquire_certreq_issuer";
rc=JNH_inquire_certreq_issuer
         (reqId, &issuer);

success=(  (rc==0)
         &&(strcmp((const char *) issuer,(const char *)SISSUER)==0)
        );
PRINTTESTRESULT(success,thistest);
if (success) printf("Issuer Name was %s.\n",issuer);

serialNumber.data=NULL;
testname[thistest]="JNH_inquire_certreq_serialnumber";
rc=JNH_inquire_certreq_serialnumber
         (reqId, &serialNumber);

success=(  ( (rc==0)
            ||(rc=ASN_VALUE_NOT_SET)
           )
        );
PRINTTESTRESULT(success,thistest);
if (serialNumber.data!=NULL)
	printf("serialNumber was %x.\n",*(uint32 *)(serialNumber.data));

// TODO - When serial number appears in the certrep, remove the Hack
HackSerial(reqId,27);
serialNumber.data=NULL;
testname[thistest]="JNH_inquire_certreq_serialnumber";
rc=JNH_inquire_certreq_serialnumber
         (reqId, &serialNumber);

success=(  (  (rc==0)
            &&(  (serialNumber.data!=NULL)
               &&(*(uint32*)serialNumber.data==27)
	      )
           )
        );
PRINTTESTRESULT(success,thistest);
if (serialNumber.data!=NULL)
	printf("serialNumber was %x.\n",*(uint32 *)(serialNumber.data));

testname[thistest]="JNH_inquire_certreq_status";
rc=JNH_inquire_certreq_status
         (reqId, &status);

success=(  (rc==0)
	 &&(status!=0)
        );
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_inquire_certreq_subjectkey_present";
rc=JNH_inquire_certreq_subjectkey_present
         (reqId, &keyPresent);

success=(  (rc==0)
         &&(keyPresent==FALSE)
        );
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_inquire_certreq_subjectkey_algorithm";
algorithm.data=NULL; algorithm.length=0;
rc=JNH_inquire_certreq_subjectkey_algorithm
         (reqId, & algorithm);

success=(rc==ASN_VALUE_NOT_SET);
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_set_certreq_subjectKey";
rc=JNH_set_certreq_subjectKey
         (reqId, keyId);

success=(rc==0);
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_inquire_certreq_subjectkey_present";
rc=JNH_inquire_certreq_subjectkey_present
         (reqId, &keyPresent);

success=(  (rc==0)
         &&(keyPresent==TRUE)
        );
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_inquire_certreq_subjectkey_algorithm";
algorithm.data=NULL; algorithm.length=0;
rc=JNH_inquire_certreq_subjectkey_algorithm
         (reqId, & algorithm);

success=(  (rc==0)
         &&(algorithm.data!=NULL)
        );
print_subject_key_alg(algorithm);
PRINTTESTRESULT(success,thistest);
if (success==0) free(algorithm.data);

testname[thistest]="JNH_inquire_certreq_startdate";
rc=JNH_inquire_certreq_startdate
         (reqId, &startDate);
                
// The first time nothing will be set, so we get an error
success=(  (  (rc==0)
            ||(rc==ASN_VALUE_NOT_SET)
           )
        );
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_set_certreq_startDate";
notBefore.year=2002;
notBefore.month=11;
notBefore.day=10;
notBefore.hour=9;
notBefore.min=8;
notBefore.sec=7;
rc=JNH_set_certreq_startDate
         (reqId, notBefore);

success=(rc==0);
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_inquire_certreq_startdate";
rc=JNH_inquire_certreq_startdate
         (reqId, &startDate);
                
success=(  (rc==0)
         &&(startDate.year==2002)
        );
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_inquire_certreq_enddate";
rc=JNH_inquire_certreq_enddate
         (reqId, &endDate);

// The first time nothing will be set, so we get an error
success=(  (  (rc==0)
            ||(rc==ASN_VALUE_NOT_SET)
           )
        );
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_set_certreq_endDate";
notAfter.year=2001;
notAfter.month=11;
notAfter.day=10;
notAfter.hour=9;
notAfter.min=8;
notAfter.sec=7;
rc=JNH_set_certreq_endDate
         (reqId, notAfter);

success=(rc==0);
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_inquire_certreq_enddate";
rc=JNH_inquire_certreq_enddate
         (reqId, &endDate);

success=(  (rc==0)
         &&(notAfter.year==2001)
        );
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_inquire_certreq_basicConstraints";
rc=JNH_inquire_certreq_basicConstraints
         (reqId, &isCaCert, &maxPathLen);

success=(rc==API_FIELD_NOT_SET);
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_set_certreq_basicConstraints";
isCaCert=TRUE;
maxPathLen=27;
rc=JNH_set_certreq_basicConstraints
         (reqId, isCaCert, maxPathLen);

success=(rc==0);
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_inquire_certreq_basicConstraints";
rc=JNH_inquire_certreq_basicConstraints
         (reqId, &isCaCert, &maxPathLen);

success=(  (rc==0)
	 &&(isCaCert==TRUE)
	 &&(maxPathLen=27)
        );
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_inquire_certreq_keyUsage";
rc=JNH_inquire_certreq_keyUsage
         (reqId, &usages);

success=(rc==API_FIELD_NOT_SET);
PRINTTESTRESULT(success,thistest);

status=JNH_save_object(reqId);
printf("status=%d\n",status);
status=JNH_reserve_object(reqId);
testname[thistest]="JNH_set_certreq_keyUsage";
keyUsage=USAGE_digitalSignature|USAGE_nonRepudiation;
rc=JNH_set_certreq_keyUsage
         (reqId, keyUsage);
rc=0;

success=(rc==0);
PRINTTESTRESULT(success,thistest);

status=JNH_save_object(reqId);
printf("status=%d\n",status);
status=JNH_reserve_object(reqId);

testname[thistest]="JNH_inquire_certreq_keyUsage";
rc=JNH_inquire_certreq_keyUsage
         (reqId, &usages);

success=(  (rc==0)
	 &&(usages=USAGE_digitalSignature|USAGE_nonRepudiation)
        );
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_set_certreq_keyUsage";
keyUsage=USAGE_dataEncipherment;
rc=JNH_set_certreq_keyUsage
         (reqId, keyUsage);

success=(rc==0);
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_inquire_certreq_keyUsage";
rc=JNH_inquire_certreq_keyUsage
         (reqId, &usages);

success=(  (rc==0)
	 &&(usages=USAGE_dataEncipherment)
        );
PRINTTESTRESULT(success,thistest);


//  End of Valid Tests =======================================

#if 0 // Dont compile invalid tests
// TODO - implement the rest of these tests

testname[thistest]="JNH_inquire_certreq_subjectkey";
rc=JNH_inquire_certreq_subjectkey
         (reqId, key);

success=(rc==0);
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_inquire_certreq_policies";
rc=JNH_inquire_certreq_policies
         (reqId, &numberPolicies, policies);

success=(rc==0);
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_inquire_certreq_authorityKeyId";
rc=JNH_inquire_certreq_authorityKeyId
         (reqId, &o_keyId, &authorityName, &serialNumber);

success=(rc==0);
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_inquire_certreq_subjectKeyId";
rc=JNH_inquire_certreq_subjectKeyId
         (reqId, subjectKeyId);

success=(rc==0);
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_inquire_certreq_privateKeyUsagePeriod";
rc=JNH_inquire_certreq_privateKeyUsagePeriod
         (reqId, &notBefore, &notAfter);

success=(rc==0);
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_inquire_certreq_policyQualifiers_CPS";
rc=JNH_inquire_certreq_policyQualifiers_CPS
         (reqId, policy, policyQualifierId, &CPS_URI);

success=(rc==0);
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_inquire_certreq_policyQualifiers_userNotice";
rc=JNH_inquire_certreq_policyQualifiers_userNotice
         (reqId, policy, policyQualifierId, &explicitText,
          &organization, &numberNotices, &notices);

success=(rc==0);
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_inquire_certreq_policyMappings";
rc=JNH_inquire_certreq_policyMappings
         (reqId, &numberMappings, issuerDomainPolicies,
          subjectDomainPolicies);

success=(rc==0);
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_inquire_certreq_nameConstraints_permittedSubtrees";
rc=JNH_inquire_certreq_nameConstraints_permittedSubtrees
         (reqId, &numberSubtrees, bases, maxLengths, minLenths);

success=(rc==0);
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_inquire_certreq_nameConstraints_excludedSubtrees";
rc=JNH_inquire_certreq_nameConstraints_excludedSubtrees
         (reqId, &numberSubtrees, bases, maxLengths, minLenths);

success=(rc==0);
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_inquire_certreq_policyConstraints";
rc=JNH_inquire_certreq_policyConstraints
         (reqId, &numberConstraints, policies,
	 &requireExplicitPolicys, &inhibitMappings);
                                   
success=(rc==0);
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_inquire_certreq_xKeyUsages";
rc=JNH_inquire_certreq_xKeyUsages
         (reqId, &numberUsages, o_usages);

success=(rc==0);
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_inquire_certreq_extensions";
rc=JNH_inquire_certreq_extensions
         (reqId, &numberExtensions, extensions, &criticals, values);

success=(rc==0);
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_add_certreq_policy";
rc=JNH_add_certreq_policy
         (reqId, policy);

success=(rc==0);
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_remove_certreq_policy";
rc=JNH_remove_certreq_policy
         (reqId, policy);

success=(rc==0);
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_clear_certreq_policy";
rc=JNH_clear_certreq_policy
         (reqId);

success=(rc==0);
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_set_certreq_authorityKeyId";
rc=JNH_set_certreq_authorityKeyId
         (reqId, o_keyId, authorityName, serialNumber);

success=(rc==0);
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_set_certreq_privateKeyUsagePeriod";
rc=JNH_set_certreq_privateKeyUsagePeriod
         (reqId, notBefore, notAfter);

success=(rc==0);
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_add_certreq_policyQualifiers_CPS";
rc=JNH_add_certreq_policyQualifiers_CPS
         (reqId, policyId, CPS_URI);

success=(rc==0);
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_remove_certreq_policyQualifiers_CPS";
rc=JNH_remove_certreq_policyQualifiers_CPS
         (reqId, policyId);

success=(rc==0);
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_clear_certreq_policyQualifiers_CPS";
rc=JNH_clear_certreq_policyQualifiers_CPS
         (reqId);

success=(rc==0);
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_add_certreq_policyQualifiers_userNotice";
rc=JNH_add_certreq_policyQualifiers_userNotice
         (reqId, policyId, explicitText, organization,
          numberNotices, notices);

success=(rc==0);
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_remove_certreq_policyQualifiers_userNotice";
rc=JNH_remove_certreq_policyQualifiers_userNotice
         (reqId, policyId);

success=(rc==0);
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_clear_certreq_policyQualifiers_userNotice";
rc=JNH_clear_certreq_policyQualifiers_userNotice
         (reqId);

success=(rc==0);
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_add_certreq_policyMapping";
rc=JNH_add_certreq_policyMapping
         (reqId, issuerDomainPolicy, subjectDomainPolicy);

success=(rc==0);
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_remove_certreq_policyMapping";
rc=JNH_remove_certreq_policyMapping
         (reqId, issuerDomainPolicy, subjectDomainPolicy);

success=(rc==0);
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_clear_certreq_policyMapping";
rc=JNH_clear_certreq_policyMapping
         (reqId);

success=(rc==0);
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_set_certreq_nameConstraints_permittedSubtrees";
rc=JNH_set_certreq_nameConstraints_permittedSubtrees
         (reqId, base, maxLength, minLength);

success=(rc==0);
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_remove_certreq_nameConstraints_permittedSubtrees";
rc=JNH_remove_certreq_nameConstraints_permittedSubtrees
         (reqId, base, maxLength, minLength);

success=(rc==0);
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_clear_certreq_nameConstraints_permittedSubtrees";
rc=JNH_clear_certreq_nameConstraints_permittedSubtrees
         (reqId);

success=(rc==0);
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_set_certreq_nameConstraints_excludedSubtrees";
rc=JNH_set_certreq_nameConstraints_excludedSubtrees
         (reqId, base, maxLength, minLength);

success=(rc==0);
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_remove_certreq_nameConstraints_excludedSubtrees";
rc=JNH_remove_certreq_nameConstraints_excludedSubtrees
         (reqId, base, maxLength, minLength);

success=(rc==0);
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_clear_certreq_nameConstraints_excludedSubtrees";
rc=JNH_clear_certreq_nameConstraints_excludedSubtrees
         (reqId);

success=(rc==0);
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_add_certreq_policyConstraints";
rc=JNH_add_certreq_policyConstraints
         (reqId, policyId, requireExplicitPolicy, inhibitMapping);

success=(rc==0);
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_remove_certreq_policyConstraints";
rc=JNH_remove_certreq_policyConstraints
         (reqId, policyId);

success=(rc==0);
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_clear_certreq_policyConstraints";
rc=JNH_clear_certreq_policyConstraints
         (reqId);

success=(rc==0);
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_add_certreq_xKeyUsages";
rc=JNH_add_certreq_xKeyUsages
         (reqId, usage);

success=(rc==0);
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_remove_certreq_xKeyUsages";
rc=JNH_remove_certreq_xKeyUsages
         (reqId, usage);

success=(rc==0);
PRINTTESTRESULT(success,thistest);
testname[thistest]="JNH_clear_certreq_xKeyUsages";
rc=JNH_clear_certreq_xKeyUsages
         (reqId);

success=(rc==0);
PRINTTESTRESULT(success,thistest);
testname[thistest]="JNH_add_certreq_extensions";
rc=JNH_add_certreq_extensions
         (reqId, extId, critical, value);

success=(rc==0);
PRINTTESTRESULT(success,thistest);
testname[thistest]="JNH_remove_certreq_extensions";
rc=JNH_remove_certreq_extensions
         (reqId, extId);

success=(rc==0);
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_clear_certreq_extensions";
rc=JNH_clear_certreq_extensions
         (reqId);
success=(rc==0);
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_create_certreq";
rc=JNH_create_certreq
         (& reqId);
success=(rc==0);
PRINTTESTRESULT(success,thistest);

// JNH_create_certificate must work for these tests to work
// Now test with replies
testname[thistest]="JNH_inquire_certreq_subject on reply #1";
rc=JNH_inquire_certreq_subject
         (repId, &subject);

success=(  (rc==0)
         &&(strcmp((const char *) subject,(const char *)RSUBJECT)==0)
        );
PRINTTESTRESULT(success,thistest);
if (success) printf("Subject Name was %s.\n",subject);

testname[thistest]="JNH_inquire_certreq_subject on reply #2";
rc=JNH_inquire_certreq_subject
         (repId, &subject);

success=(  (rc==0)
         &&(strcmp((const char *) subject,(const char *)RSUBJECT)==0)
        );
PRINTTESTRESULT(success,thistest);
if (success) printf("Subject Name was %s.\n",subject);

testname[thistest]="JNH_set_certreq_subject on reply";
rc=JNH_set_certreq_subject
         (repId, SSUBJECT);

success=(rc==ASN_INVALID_ENCODING);
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_inquire_certreq_subject with reply";
rc=JNH_inquire_certreq_subject
         (repId, &subject);

success=(  (rc==0)
         &&(strcmp((const char *) subject,(const char *)RSUBJECT)==0)
        );
PRINTTESTRESULT(success,thistest);
if (success) printf("Subject Name was %s.\n",subject);

testname[thistest]="JNH_inquire_certreq_issuer from reply";
rc=JNH_inquire_certreq_issuer
         (repId, &issuer);

success=(  (rc==0)
         &&(strcmp((const char *) issuer,(const char *)RISSUER)==0)
        );
PRINTTESTRESULT(success,thistest);
if (success) printf("Issuer Name was %s.\n",issuer);

testname[thistest]="JNH_set_certreq_issuer from reply";
rc=JNH_set_certreq_issuer
         (repId, SISSUER);

success=(rc==ASN_INVALID_ENCODING);
PRINTTESTRESULT(success,thistest);

testname[thistest]="JNH_inquire_certreq_issuer from reply";
rc=JNH_inquire_certreq_issuer
         (repId, &issuer);

success=(  (rc==0)
         &&(strcmp((const char *) issuer,(const char *)RISSUER)==0)
        );
PRINTTESTRESULT(success,thistest);
if (success) printf("Issuer Name was %s.\n",issuer);

#endif /* 0 */ // Dont compile invalid tests

if ( strcmp(parm1,"save") != 0 )
{ // delete the stuff
// The locks on reqId and repId from above are required for these deletes
//
status=JNH_reserve_object(prgId);
if ( status != 0 ) 
{
	PEM(status);
//	exit(status);
}

if (status=JNH_delete_object(prgId))
	{
	printf("Delete of PreReg Object (%d) failed.\n",prgId);
	PEM(status);
	}
if (status=JNH_delete_object(reqId))
	{
	printf("Delete of Request Object (%d) failed.\n",reqId);
	PEM(status);
	}
if (status=JNH_delete_object(repId))
	{
	printf("Delete of Reply Object (%d) failed.\n",repId);
	PEM(status);
	}

}
else
{
rc=JNH_inquire_certreq_enddate
         (reqId, &endDate);


printf("inquire_certreq_endate(%d)=%d.\n",reqId,rc);
printf("Date=%d/%d/%d, %d:%d:%d\n",
endDate.year,
endDate.month,
endDate.day,
endDate.hour,
endDate.min,
endDate.sec);

rc=JNH_inquire_certreq_subject
         (reqId, &subject);
printf("inquire_certreq_subject(%d)=%d.\n",reqId,rc);
if ( subject==NULL) printf("subject=(null)\n");
else printf("Subject Name=%s.\n",subject);

printf("status for save object(%d)=%d\n",reqId,JNH_save_object(reqId));
}
if ( lastfailure == 0 ) printf ("\nAll Tests Passed!\n");
else printf("\nThere were %d failed tests, last failure was %d.\n",numfailure,lastfailure);
return lastfailure;
}

}
