Ejemplo n.º 1
0
/*
 * FUNCTION: PKIX_PL_HttpCertStore_Create
 * (see comments in pkix_samples_modules.h)
 */
PKIX_Error *
PKIX_PL_HttpCertStore_Create(
        PKIX_PL_HttpClient *client,
        PKIX_PL_GeneralName *location,
        PKIX_CertStore **pCertStore,
        void *plContext)
{
        PKIX_PL_String *locationString = NULL;
        char *locationAscii = NULL;
        PKIX_UInt32 len = 0;

        PKIX_ENTER(CERTSTORE, "PKIX_PL_HttpCertStore_Create");
        PKIX_NULLCHECK_TWO(location, pCertStore);

        PKIX_TOSTRING(location, &locationString, plContext,
                PKIX_GENERALNAMETOSTRINGFAILED);

        PKIX_CHECK(PKIX_PL_String_GetEncoded
                (locationString,
                PKIX_ESCASCII,
                (void **)&locationAscii,
                &len,
                plContext),
                PKIX_STRINGGETENCODEDFAILED);

        PKIX_CHECK(pkix_pl_HttpCertStore_CreateWithAsciiName
                (client, locationAscii, pCertStore, plContext),
                PKIX_HTTPCERTSTORECREATEWITHASCIINAMEFAILED);

cleanup:

        PKIX_DECREF(locationString);

        PKIX_RETURN(CERTSTORE);
}
Ejemplo n.º 2
0
/*
 * FUNCTION: PKIX_PL_Date_Create_UTCTime (see comments in pkix_pl_pki.h)
 */
PKIX_Error *
PKIX_PL_Date_Create_UTCTime(
        PKIX_PL_String *stringRep,
        PKIX_PL_Date **pDate,
        void *plContext)
{
        PKIX_PL_Date *date = NULL;
        char *asciiString = NULL;
        PKIX_UInt32 escAsciiLength;
        SECStatus rv;
        PRTime time;

        PKIX_ENTER(DATE, "PKIX_PL_Date_Create_UTCTime");
        PKIX_NULLCHECK_ONE(pDate);

        if (stringRep == NULL){
                PKIX_DATE_DEBUG("\t\tCalling PR_Now).\n");
                time = PR_Now();
        } else {
                /* convert the input PKIX_PL_String to PKIX_ESCASCII */
                PKIX_CHECK(PKIX_PL_String_GetEncoded
                            (stringRep,
                            PKIX_ESCASCII,
                            (void **)&asciiString,
                            &escAsciiLength,
                            plContext),
                            PKIX_STRINGGETENCODEDFAILED);

                PKIX_DATE_DEBUG("\t\tCalling DER_AsciiToTime).\n");
                /* DER_AsciiToTime only supports UTCTime (2-digit years) */
                rv = DER_AsciiToTime(&time, asciiString);
                if (rv != SECSuccess){
                        PKIX_ERROR(PKIX_DERASCIITOTIMEFAILED);
                }
        }

        /* create a PKIX_PL_Date object */
        PKIX_CHECK(PKIX_PL_Object_Alloc
                    (PKIX_DATE_TYPE,
                    sizeof (PKIX_PL_Date),
                    (PKIX_PL_Object **)&date,
                    plContext),
                    PKIX_COULDNOTCREATEOBJECT);

        /* populate the nssTime field */
        date->nssTime = time;
        *pDate = date;

cleanup:
        PKIX_FREE(asciiString);

        PKIX_RETURN(DATE);
}
Ejemplo n.º 3
0
/*
 * FUNCTION: pkix_pl_CollectionCertStoreContext_PopulateCRL
 * DESCRIPTION:
 *
 *  Create list of CRLs from *.crl files at directory specified in dirName,
 *  Not recursive to sub-dirctory. Also assume the directory contents are
 *  not changed dynamically.
 *
 * PARAMETERS
 *  "colCertStoreContext" - Address of CollectionCertStoreContext
 *              where the dirName is specified and where the return
 *              CRLs are stored as a list. Must be non-NULL.
 *  "plContext" - Platform-specific context pointer.
 *
 * THREAD SAFETY:
 *  Not Thread Safe - A lock at top level is required.
 *
 * RETURNS:
 *  Returns NULL if the function succeeds.
 *  Returns a CollectionCertStoreContext Error if the function fails in
 *              a non-fatal way.
 *  Returns a Fatal Error if the function fails in an unrecoverable way.
 */
static PKIX_Error *
pkix_pl_CollectionCertStoreContext_PopulateCRL(
        PKIX_PL_CollectionCertStoreContext *colCertStoreContext,
        void *plContext)
{
        PKIX_List *crlList = NULL;
        PKIX_PL_CRL *crlItem = NULL;
        char *dirName = NULL;
        char *pathName = NULL;
        PKIX_UInt32 dirNameLen = 0;
        PRErrorCode prError = 0;
        PRDir *dir = NULL;
        PRDirEntry *dirEntry = NULL;

        PKIX_ENTER(COLLECTIONCERTSTORECONTEXT,
                    "pkix_pl_CollectionCertStoreContext_PopulateCRL");
        PKIX_NULLCHECK_ONE(colCertStoreContext);

        /* convert directory to ascii */

        PKIX_CHECK(PKIX_PL_String_GetEncoded
                    (colCertStoreContext->storeDir,
                    PKIX_ESCASCII,
                    (void **)&dirName,
                    &dirNameLen,
                    plContext),
                    PKIX_STRINGGETENCODEDFAILED);

        /* create CRL list, if no CRL file, should return an empty list */

        PKIX_CHECK(PKIX_List_Create(&crlList, plContext),
                    PKIX_LISTCREATEFAILED);

        /* open directory and read in .crl files */

        PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG("\t\t Calling PR_OpenDir.\n");
        dir = PR_OpenDir(dirName);

        if (!dir) {
                PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG_ARG
                        ("\t\t Directory Name:%s\n", dirName);
                PKIX_ERROR(PKIX_CANNOTOPENCOLLECTIONCERTSTORECONTEXTDIRECTORY);
        }

        PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG("\t\t Calling PR_ReadDir.\n");
        dirEntry = PR_ReadDir(dir, PR_SKIP_HIDDEN | PR_SKIP_BOTH);

        if (!dirEntry) {
                PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
                        ("\t\t Empty directory.\n");
                PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
                        ("\t\t Calling PR_GetError.\n");
                prError = PR_GetError();
        }

        PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG("\t\t Calling PR_SetError.\n");
        PR_SetError(0, 0);

        while (dirEntry != NULL && prError == 0) {
                if (PL_strrstr(dirEntry->name, ".crl") ==
                    dirEntry->name + PL_strlen(dirEntry->name) - 4) {

                        PKIX_CHECK_ONLY_FATAL
                                (PKIX_PL_Malloc
                                (dirNameLen + PL_strlen(dirEntry->name) + 2,
                                (void **)&pathName,
                                plContext),
                                PKIX_MALLOCFAILED);

                        if ((!PKIX_ERROR_RECEIVED) && (pathName != NULL)){

                                PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
                                    ("\t\t Calling PL_strcpy for dirName.\n");
                                PL_strcpy(pathName, dirName);
                                PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
                                    ("\t\t Calling PL_strcat for dirName.\n");
                                PL_strcat(pathName, "/");
                                PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
                                        ("\t\t Calling PL_strcat for /.\n");
                                PL_strcat(pathName, dirEntry->name);

                        PKIX_CHECK_ONLY_FATAL
                                (pkix_pl_CollectionCertStoreContext_CreateCRL
                                (pathName, &crlItem, plContext),
                                PKIX_COLLECTIONCERTSTORECONTEXTCREATECRLFAILED);

                                if (!PKIX_ERROR_RECEIVED){
                                        PKIX_CHECK_ONLY_FATAL
                                                (PKIX_List_AppendItem
                                                (crlList,
                                                (PKIX_PL_Object *)crlItem,
                                                plContext),
                                                PKIX_LISTAPPENDITEMFAILED);
                                }
                        }

                        PKIX_DECREF(crlItem);
                        PKIX_FREE(pathName);
                }

                PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
                        ("\t\t Calling PR_SetError.\n");
                PR_SetError(0, 0);

                PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
                        ("\t\t Calling PR_ReadDir.\n");
                dirEntry = PR_ReadDir(dir, PR_SKIP_HIDDEN | PR_SKIP_BOTH);

                if (!dirEntry) {
                    PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
                        ("\t\t Calling PR_GetError.\n");
                    prError = PR_GetError();
                }
        }

        if ((prError != 0) && (prError != PR_NO_MORE_FILES_ERROR)) {
                PKIX_ERROR(PKIX_COLLECTIONCERTSTORECONTEXTGETSELECTCRLFAILED);
        }

        PKIX_CHECK(PKIX_List_SetImmutable(crlList, plContext),
                    PKIX_LISTSETIMMUTABLEFAILED);

        PKIX_INCREF(crlList);
        colCertStoreContext->crlList = crlList;

cleanup:
        if (dir) {
                PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
                        ("\t\t Calling PR_CloseDir.\n");
                PR_CloseDir(dir);
        }

        PKIX_FREE(pathName);
        PKIX_FREE(dirName);

        if (PKIX_ERROR_RECEIVED){
                PKIX_DECREF(crlList);
        }

        PKIX_DECREF(crlItem);
        PKIX_DECREF(crlList);

        PKIX_RETURN(COLLECTIONCERTSTORECONTEXT);
}
PKIX_Error *
pkix_pl_AIAMgr_GetHTTPCerts(
        PKIX_PL_AIAMgr *aiaMgr,
	PKIX_PL_InfoAccess *ia,
	void **pNBIOContext,
	PKIX_List **pCerts,
        void *plContext)
{
        PKIX_PL_GeneralName *location = NULL;
        PKIX_PL_String *locationString = NULL;
	PKIX_UInt32 len = 0;
	PRUint16 port = 0;
	const SEC_HttpClientFcn *httpClient = NULL;
	const SEC_HttpClientFcnV1 *hcv1 = NULL;
	SECStatus rv = SECFailure;
	SEC_HTTP_SERVER_SESSION serverSession = NULL;
	SEC_HTTP_REQUEST_SESSION requestSession = NULL;	
	char *path = NULL;
	char *hostname = NULL;
	char *locationAscii = NULL;
	void *nbio = NULL;
	PRUint16 responseCode = 0;
	const char *responseContentType = NULL;
	const char *responseData = NULL;

        PKIX_ENTER(AIAMGR, "pkix_pl_AIAMgr_GetHTTPCerts");
        PKIX_NULLCHECK_FOUR(aiaMgr, ia, pNBIOContext, pCerts);

        nbio = *pNBIOContext;
        *pNBIOContext = NULL;
        *pCerts = NULL;

        if (nbio == NULL) { /* a new request */

                PKIX_CHECK(PKIX_PL_InfoAccess_GetLocation
                        (ia, &location, plContext),
                       PKIX_INFOACCESSGETLOCATIONFAILED);

                /* find or create httpClient = default client */
		httpClient = SEC_GetRegisteredHttpClient();
		aiaMgr->client.hdata.httpClient = httpClient;
		if (!httpClient)
		    PKIX_ERROR(PKIX_OUTOFMEMORY);

		if (httpClient->version == 1) {

                        PKIX_UInt32 timeout =
                             ((PKIX_PL_NssContext*)plContext)->timeoutSeconds;

			hcv1 = &(httpClient->fcnTable.ftable1);

			/* create server session */
			PKIX_TOSTRING(location, &locationString, plContext,
				PKIX_GENERALNAMETOSTRINGFAILED);

			PKIX_CHECK(PKIX_PL_String_GetEncoded
				(locationString,
				PKIX_ESCASCII,
				(void **)&locationAscii,
				&len,
				plContext),
				PKIX_STRINGGETENCODEDFAILED);

                        rv = CERT_ParseURL(locationAscii, &hostname, &port,
                                            &path);
			if ((rv != SECSuccess) ||
			    (hostname == NULL) ||
			    (path == NULL)) {
				PKIX_ERROR(PKIX_URLPARSINGFAILED);
			}

                        rv = (*hcv1->createSessionFcn)(hostname, port, 
                                                       &serverSession);
	                if (rv != SECSuccess) {
				PKIX_ERROR(PKIX_HTTPCLIENTCREATESESSIONFAILED);
			}

			aiaMgr->client.hdata.serverSession = serverSession;

			/* create request session */
                        rv = (*hcv1->createFcn)(serverSession, "http", path,
                        	"GET", PR_SecondsToInterval(timeout),
                                 &requestSession);
                	if (rv != SECSuccess) {
                        	PKIX_ERROR(PKIX_HTTPSERVERERROR);
                	}

			aiaMgr->client.hdata.requestSession = requestSession;
		} else {
			PKIX_ERROR(PKIX_UNSUPPORTEDVERSIONOFHTTPCLIENT);
		}
	}

	httpClient = aiaMgr->client.hdata.httpClient;

	if (httpClient->version == 1) {
                PRUint32 responseDataLen = 
                   ((PKIX_PL_NssContext*)plContext)->maxResponseLength;

		hcv1 = &(httpClient->fcnTable.ftable1);
		requestSession = aiaMgr->client.hdata.requestSession;

		/* trySendAndReceive */
                rv = (*hcv1->trySendAndReceiveFcn)(requestSession,
                                 (PRPollDesc **)&nbio,
                                 &responseCode,
                                 (const char **)&responseContentType,
                                 NULL, /* &responseHeaders */
                                 (const char **)&responseData,
                                 &responseDataLen);

                if (rv != SECSuccess) {
                        PKIX_ERROR(PKIX_HTTPSERVERERROR);
                }

                if (nbio != 0) {
                        *pNBIOContext = nbio;
                        goto cleanup;
                }

		PKIX_CHECK(pkix_pl_HttpCertStore_ProcessCertResponse
	                (responseCode,
	                responseContentType,
	                responseData,
	                responseDataLen,
	                pCerts,
	                plContext),
	                PKIX_HTTPCERTSTOREPROCESSCERTRESPONSEFAILED);
                
                /* Session and request cleanup in case of success */
                if (aiaMgr->client.hdata.requestSession != NULL) {
                    (*hcv1->freeFcn)(aiaMgr->client.hdata.requestSession);
                    aiaMgr->client.hdata.requestSession = NULL;
                }
                if (aiaMgr->client.hdata.serverSession != NULL) {
                    (*hcv1->freeSessionFcn)(aiaMgr->client.hdata.serverSession);
                    aiaMgr->client.hdata.serverSession = NULL;
                }
                aiaMgr->client.hdata.httpClient = 0; /* callback fn */

        } else  {
		PKIX_ERROR(PKIX_UNSUPPORTEDVERSIONOFHTTPCLIENT);
	}

cleanup:
        /* Session and request cleanup in case of error. Passing through without cleanup
         * if interrupted by blocked IO. */
        if (PKIX_ERROR_RECEIVED && aiaMgr) {
            if (aiaMgr->client.hdata.requestSession != NULL) {
                (*hcv1->freeFcn)(aiaMgr->client.hdata.requestSession);
                aiaMgr->client.hdata.requestSession = NULL;
            }
            if (aiaMgr->client.hdata.serverSession != NULL) {
                (*hcv1->freeSessionFcn)(aiaMgr->client.hdata.serverSession);
                aiaMgr->client.hdata.serverSession = NULL;
            }
            aiaMgr->client.hdata.httpClient = 0; /* callback fn */
        }

        PKIX_DECREF(location);
        PKIX_DECREF(locationString);

        if (locationAscii) {
            PORT_Free(locationAscii);
        }
        if (hostname) {
            PORT_Free(hostname);
        }
        if (path) {
            PORT_Free(path);
        }

        PKIX_RETURN(AIAMGR);
}
Ejemplo n.º 5
0
/*
 * FUNCTION: PKIX_PL_GeneralName_Create (see comments in pkix_pl_pki.h)
 */
PKIX_Error *
PKIX_PL_GeneralName_Create(
        PKIX_UInt32 nameType,
        PKIX_PL_String *stringRep,
        PKIX_PL_GeneralName **pGName,
        void *plContext)
{
        PKIX_PL_X500Name *pkixDN = NULL;
        PKIX_PL_OID *pkixOID = NULL;
        SECItem *secItem = NULL;
        char *asciiString = NULL;
        PKIX_UInt32 length = 0;
        PKIX_PL_GeneralName *genName = NULL;
        CERTGeneralName *nssGenName = NULL;
        CERTGeneralNameList *nssGenNameList = NULL;
        CERTName *nssCertName = NULL;
        PLArenaPool *arena = NULL;

        PKIX_ENTER(GENERALNAME, "PKIX_PL_GeneralName_Create");
        PKIX_NULLCHECK_TWO(pGName, stringRep);

        PKIX_CHECK(PKIX_PL_String_GetEncoded
                    (stringRep,
                    PKIX_ESCASCII,
                    (void **)&asciiString,
                    &length,
                    plContext),
                    PKIX_STRINGGETENCODEDFAILED);

        /* Create a temporary CERTGeneralName */
        PKIX_GENERALNAME_DEBUG("\t\tCalling PL_strlen).\n");
        length = PL_strlen(asciiString);
        PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_AllocItem).\n");
        secItem = SECITEM_AllocItem(NULL, NULL, length);
        PKIX_GENERALNAME_DEBUG("\t\tCalling PORT_Memcpy).\n");
        (void) PORT_Memcpy(secItem->data, asciiString, length);
        PKIX_CERT_DEBUG("\t\tCalling PORT_NewArena).\n");
        arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
        if (arena == NULL) {
                PKIX_ERROR(PKIX_OUTOFMEMORY);
        }
        PKIX_GENERALNAME_DEBUG("\t\tCalling CERT_NewGeneralName).\n");
        nssGenName = CERT_NewGeneralName(arena, nameType);
        if (nssGenName == NULL) {
                PKIX_ERROR(PKIX_ALLOCATENEWCERTGENERALNAMEFAILED);
        }

        switch (nameType) {
        case certRFC822Name:
        case certDNSName:
        case certURI:
                nssGenName->name.other = *secItem;
                break;

        case certDirectoryName:

                PKIX_CHECK(PKIX_PL_X500Name_Create
                            (stringRep, &pkixDN, plContext),
                            PKIX_X500NAMECREATEFAILED);

                PKIX_GENERALNAME_DEBUG("\t\tCalling CERT_AsciiToName).\n");
                nssCertName = CERT_AsciiToName(asciiString);
                nssGenName->name.directoryName = *nssCertName;
                break;

        case certRegisterID:
                PKIX_CHECK(PKIX_PL_OID_Create
                            (asciiString, &pkixOID, plContext),
                            PKIX_OIDCREATEFAILED);
                nssGenName->name.other = *secItem;
                break;
        default:
                /* including IPAddress, EDIPartyName, OtherName, X400Address */
                PKIX_ERROR(PKIX_UNABLETOCREATEGENERALNAMEOFTHISTYPE);
        }

        /* create a PKIX_PL_GeneralName object */
        PKIX_CHECK(PKIX_PL_Object_Alloc
                    (PKIX_GENERALNAME_TYPE,
                    sizeof (PKIX_PL_GeneralName),
                    (PKIX_PL_Object **)&genName,
                    plContext),
                    PKIX_COULDNOTCREATEOBJECT);

        /* create a CERTGeneralNameList */
        nssGenName->type = nameType;
        PKIX_GENERALNAME_DEBUG("\t\tCalling CERT_CreateGeneralNameList).\n");
        nssGenNameList = CERT_CreateGeneralNameList(nssGenName);
        if (nssGenNameList == NULL) {
                PKIX_ERROR(PKIX_CERTCREATEGENERALNAMELISTFAILED);
        }
        genName->nssGeneralNameList = nssGenNameList;

        /* initialize fields */
        genName->type = nameType;
        genName->directoryName = pkixDN;
        genName->OthName = NULL;
        genName->other = secItem;
        genName->oid = pkixOID;

        *pGName = genName;
cleanup:

        PKIX_FREE(asciiString);

        if (nssCertName != NULL) {
                PKIX_CERT_DEBUG("\t\tCalling CERT_DestroyName).\n");
                CERT_DestroyName(nssCertName);
        }

        if (arena){ /* will free nssGenName */
                PKIX_CERT_DEBUG("\t\tCalling PORT_FreeArena).\n");
                PORT_FreeArena(arena, PR_FALSE);
        }

        if (PKIX_ERROR_RECEIVED){
                PKIX_DECREF(pkixDN);
                PKIX_DECREF(pkixOID);

                PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_FreeItem).\n");
                if (secItem){
                        SECITEM_FreeItem(secItem, PR_TRUE);
                        secItem = NULL;
                }
        }

        PKIX_RETURN(GENERALNAME);
}
int dumpcert(int argc, char *argv[])
{

        PKIX_PL_String *string = NULL;
        PKIX_PL_Cert *cert = NULL;
        PKIX_Error *error = NULL;
        char *ascii = NULL;
        PKIX_UInt32 length = 0;
        PKIX_UInt32 j = 0;
	PKIX_Boolean useArenas = PKIX_FALSE;
        PKIX_UInt32 actualMinorVersion;

        PKIX_TEST_STD_VARS();

        if (argc == 1){
                printUsage();
                return (0);
        }

        useArenas = PKIX_TEST_ARENAS_ARG(argv[1]);

        PKIX_Initialize
                (PKIX_TRUE, /* nssInitNeeded */
                useArenas,
                PKIX_MAJOR_VERSION,
                PKIX_MINOR_VERSION,
                PKIX_MINOR_VERSION,
                &actualMinorVersion,
                &plContext);

        cert = createCert(argv[1+j]);

        if (cert){

                error = PKIX_PL_Object_ToString
                        ((PKIX_PL_Object *)cert, &string, plContext);

                if (error){
                        printFailure("Unable to get string representation "
                                    "of cert");
                        goto cleanup;
                }

                error = PKIX_PL_String_GetEncoded
                        (string,
                        PKIX_ESCASCII,
                        (void **)&ascii,
                        &length,
                        plContext);

                if (error || !ascii){
                        printFailure("Unable to get ASCII encoding of string");
                        goto cleanup;
                }

                (void) printf("OUTPUT:\n%s\n", ascii);

        } else {
                printFailure("Unable to create certificate");
                goto cleanup;
        }

cleanup:

        if (cert){
                PKIX_PL_Object_DecRef((PKIX_PL_Object *)(cert), plContext);
        }

        if (string){
                PKIX_PL_Object_DecRef((PKIX_PL_Object *)(string), plContext);
        }

        if (ascii){
                PKIX_PL_Free((PKIX_PL_Object *)(ascii), plContext);
        }

        PKIX_Shutdown(plContext);

        PKIX_TEST_RETURN();

        endTests("DUMPCERT");

        return (0);
}