/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the PKIX-C library. * * The Initial Developer of the Original Code is * Sun Microsystems, Inc. * Portions created by the Initial Developer are * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved. * * Contributor(s): * Sun Microsystems, Inc. * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ /* * testutil.c * * Utility error handling functions * */ #include "testutil.h" /* * static global variable to keep track of total number of errors for * a particular test suite (eg. all the OID tests) */ static int errCount = 0; /* * FUNCTION: startTests * DESCRIPTION: * * Prints standard message for starting the test suite with the name pointed * to by "testName". This function should be called in the beginning of every * test suite. * * PARAMETERS: * "testName" * Address of string representing name of test suite. * THREAD SAFETY: * Not Thread Safe - assumes exclusive access to "errCount" * (see Thread Safety Definitions in Programmer's Guide) * RETURNS: * Returns nothing. */ void startTests(char *testName) { (void) printf("*START OF TESTS FOR %s:\n", testName); errCount = 0; } /* * FUNCTION: endTests * DESCRIPTION: * * Prints standard message for ending the test suite with the name pointed * to by "testName", followed by a success/failure message. This function * should be called at the end of every test suite. * * PARAMETERS: * "testName" * Address of string representing name of test suite. * THREAD SAFETY: * Not Thread Safe - assumes exclusive access to "errCount" * (see Thread Safety Definitions in Programmer's Guide) * RETURNS: * Returns nothing. */ void endTests(char *testName) { char plural = ' '; (void) printf("*END OF TESTS FOR %s: ", testName); if (errCount > 0) { if (errCount > 1) plural = 's'; (void) printf("%d SUBTEST%c FAILED.\n\n", errCount, plural); } else { (void) printf("ALL TESTS COMPLETED SUCCESSFULLY.\n\n"); } } /* * FUNCTION: subTest * DESCRIPTION: * * Prints standard message for starting the subtest with the name pointed to * by "subTestName". This function should be called at the beginning of each * subtest. * * PARAMETERS: * "subTestName" * Address of string representing name of subTest. * THREAD SAFETY: * Thread Safe (see Thread Safety Definitions in Programmer's Guide) * RETURNS: * Returns nothing. */ void subTest(char *subTestName) { (void) printf("TESTING: %s ...\n", subTestName); } /* * FUNCTION: testErrorUndo * DESCRIPTION: * * Decrements the global variable "errCount" and prints a test failure * expected message followed by the string pointed to by "msg". This function * should be called when an expected error condition is encountered in the * tests. Calling this function *correct* the previous errCount increment. * It should only be called ONCE per subtest. * * PARAMETERS: * "msg" * Address of text of error message. * THREAD SAFETY: * Not Thread Safe - assumes exclusive access to "errCount" * (see Thread Safety Definitions in Programmer's Guide) * RETURNS: * Returns nothing. */ void testErrorUndo(char *msg) { --errCount; (void) printf("TEST FAILURE *** EXPECTED *** :%s\n", msg); } /* * FUNCTION: testError * DESCRIPTION: * * Increments the global variable "errCount" and prints a standard test * failure message followed by the string pointed to by "msg". This function * should be called when an unexpected error condition is encountered in the * tests. It should only be called ONCE per subtest. * * PARAMETERS: * "msg" * Address of text of error message. * THREAD SAFETY: * Not Thread Safe - assumes exclusive access to "errCount" * (see Thread Safety Definitions in Programmer's Guide) * RETURNS: * Returns nothing. */ void testError(char *msg) { ++errCount; (void) printf("TEST FAILURE: %s\n", msg); } /* * FUNCTION: PKIX_String2ASCII * DESCRIPTION: * * Converts String object pointed to by "string" to its ASCII representation * and returns the converted value. Returns NULL upon failure. * * XXX Might want to use ESCASCII_DEBUG to show control characters, etc. * * PARAMETERS: * "string" * Address of String to be converted to ASCII. Must be non-NULL. * "plContext" * Platform-specific context pointer. * THREAD SAFETY: * Thread Safe (see Thread Safety Definitions in Programmer's Guide) * RETURNS: * Returns the ASCII representation of "string" upon success; * NULL upon failure. */ char * PKIX_String2ASCII(PKIX_PL_String *string, void *plContext) { PKIX_UInt32 length; char *asciiString = NULL; PKIX_Error *errorResult; errorResult = PKIX_PL_String_GetEncoded (string, PKIX_ESCASCII, (void **)&asciiString, &length, plContext); if (errorResult) goto cleanup; cleanup: if (errorResult){ return (NULL); } return (asciiString); } /* * FUNCTION: PKIX_Error2ASCII * DESCRIPTION: * * Converts Error pointed to by "error" to its ASCII representation and * returns the converted value. Returns NULL upon failure. * * PARAMETERS: * "error" * Address of Error to be converted to ASCII. Must be non-NULL. * "plContext" * Platform-specific context pointer. * THREAD SAFETY: * Thread Safe (see Thread Safety Definitions in Programmer's Guide) * RETURNS: * Returns the ASCII representation of "error" upon success; * NULL upon failure. */ char * PKIX_Error2ASCII(PKIX_Error *error, void *plContext) { PKIX_UInt32 length; char *asciiString = NULL; PKIX_PL_String *pkixString = NULL; PKIX_Error *errorResult = NULL; errorResult = PKIX_PL_Object_ToString ((PKIX_PL_Object*)error, &pkixString, plContext); if (errorResult) goto cleanup; errorResult = PKIX_PL_String_GetEncoded (pkixString, PKIX_ESCASCII, (void **)&asciiString, &length, plContext); cleanup: if (pkixString){ if (PKIX_PL_Object_DecRef ((PKIX_PL_Object*)pkixString, plContext)){ return (NULL); } } if (errorResult){ return (NULL); } return (asciiString); } /* * FUNCTION: PKIX_Object2ASCII * DESCRIPTION: * * Converts Object pointed to by "object" to its ASCII representation and * returns the converted value. Returns NULL upon failure. * * PARAMETERS: * "object" * Address of Object to be converted to ASCII. Must be non-NULL. * THREAD SAFETY: * Thread Safe (see Thread Safety Definitions in Programmer's Guide) * RETURNS: * Returns the ASCII representation of "object" upon success; * NULL upon failure. */ char * PKIX_Object2ASCII(PKIX_PL_Object *object) { PKIX_UInt32 length; char *asciiString = NULL; PKIX_PL_String *pkixString = NULL; PKIX_Error *errorResult = NULL; errorResult = PKIX_PL_Object_ToString (object, &pkixString, NULL); if (errorResult) goto cleanup; errorResult = PKIX_PL_String_GetEncoded (pkixString, PKIX_ESCASCII, (void **)&asciiString, &length, NULL); cleanup: if (pkixString){ if (PKIX_PL_Object_DecRef((PKIX_PL_Object*)pkixString, NULL)){ return (NULL); } } if (errorResult){ return (NULL); } return (asciiString); } /* * FUNCTION: PKIX_Cert2ASCII * DESCRIPTION: * * Converts Cert pointed to by "cert" to its partial ASCII representation and * returns the converted value. Returns NULL upon failure. * * PARAMETERS: * "cert" * Address of Cert to be converted to ASCII. Must be non-NULL. * THREAD SAFETY: * Thread Safe (see Thread Safety Definitions in Programmer's Guide) * RETURNS: * Returns the partial ASCII representation of "cert" upon success; * NULL upon failure. */ char * PKIX_Cert2ASCII(PKIX_PL_Cert *cert) { PKIX_PL_X500Name *issuer = NULL; void *issuerAscii = NULL; PKIX_PL_X500Name *subject = NULL; void *subjectAscii = NULL; void *asciiString = NULL; PKIX_Error *errorResult = NULL; PKIX_UInt32 numChars; /* Issuer */ errorResult = PKIX_PL_Cert_GetIssuer(cert, &issuer, NULL); if (errorResult) goto cleanup; issuerAscii = PKIX_Object2ASCII((PKIX_PL_Object*)issuer); /* Subject */ errorResult = PKIX_PL_Cert_GetSubject(cert, &subject, NULL); if (errorResult) goto cleanup; if (subject){ subjectAscii = PKIX_Object2ASCII((PKIX_PL_Object*)subject); } errorResult = PKIX_PL_Malloc(200, &asciiString, NULL); if (errorResult) goto cleanup; numChars = PR_snprintf (asciiString, 200, "Issuer=%s\nSubject=%s\n", issuerAscii, subjectAscii); if (!numChars) goto cleanup; cleanup: if (issuer){ if (PKIX_PL_Object_DecRef((PKIX_PL_Object*)issuer, NULL)){ return (NULL); } } if (subject){ if (PKIX_PL_Object_DecRef((PKIX_PL_Object*)subject, NULL)){ return (NULL); } } if (PKIX_PL_Free((PKIX_PL_Object*)issuerAscii, NULL)){ return (NULL); } if (PKIX_PL_Free((PKIX_PL_Object*)subjectAscii, NULL)){ return (NULL); } if (errorResult){ return (NULL); } return (asciiString); } /* * FUNCTION: testHashcodeHelper * DESCRIPTION: * * Computes the hashcode of the Object pointed to by "goodObject" and the * Object pointed to by "otherObject" and compares them. If the result of the * comparison is not the desired match as specified by "match", an error * message is generated. * * PARAMETERS: * "goodObject" * Address of an object. Must be non-NULL. * "otherObject" * Address of another object. Must be non-NULL. * "match" * Boolean value representing the desired comparison result. * "plContext" * Platform-specific context pointer. * THREAD SAFETY: * Thread Safe (see Thread Safety Definitions in Programmer's Guide) * RETURNS: * Returns nothing. */ void testHashcodeHelper( PKIX_PL_Object *goodObject, PKIX_PL_Object *otherObject, PKIX_Boolean match, void *plContext) { PKIX_UInt32 goodHash; PKIX_UInt32 otherHash; PKIX_Boolean cmpResult; PKIX_TEST_STD_VARS(); PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Hashcode ((PKIX_PL_Object *)goodObject, &goodHash, plContext)); PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Hashcode ((PKIX_PL_Object *)otherObject, &otherHash, plContext)); cmpResult = (goodHash == otherHash); if ((match && !cmpResult) || (!match && cmpResult)){ testError("unexpected mismatch"); (void) printf("Hash1:\t%d\n", goodHash); (void) printf("Hash2:\t%d\n", otherHash); } cleanup: PKIX_TEST_RETURN(); } /* * FUNCTION: testToStringHelper * DESCRIPTION: * * Calls toString on the Object pointed to by "goodObject" and compares the * result to the string pointed to by "expected". If the results are not * equal, an error message is generated. * * PARAMETERS: * "goodObject" * Address of Object. Must be non-NULL. * "expected" * Address of the desired string. * "plContext" * Platform-specific context pointer. * THREAD SAFETY: * Thread Safe (see Thread Safety Definitions in Programmer's Guide) * RETURNS: * Returns nothing. */ void testToStringHelper( PKIX_PL_Object *goodObject, char *expected, void *plContext) { PKIX_PL_String *stringRep = NULL; char *actual = NULL; PKIX_TEST_STD_VARS(); PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_ToString (goodObject, &stringRep, plContext)); actual = PKIX_String2ASCII(stringRep, plContext); if (actual == NULL){ pkixTestErrorMsg = "PKIX_String2ASCII Failed"; goto cleanup; } /* * If you are having trouble matching the string, uncomment the * PL_strstr function to figure out what's going on. */ /* if (PL_strstr(actual, expected) == NULL){ testError("PL_strstr failed"); } */ if (PL_strcmp(actual, expected) != 0){ testError("unexpected mismatch"); (void) printf("Actual value:\t%s\n", actual); (void) printf("Expected value:\t%s\n", expected); } cleanup: PKIX_PL_Free(actual, plContext); PKIX_TEST_DECREF_AC(stringRep); PKIX_TEST_RETURN(); } /* * FUNCTION: testEqualsHelper * DESCRIPTION: * * Checks if the Object pointed to by "goodObject" is Equal to the Object * pointed to by "otherObject". If the result of the check is not the desired * match as specified by "match", an error message is generated. * * PARAMETERS: * "goodObject" * Address of an Object. Must be non-NULL. * "otherObject" * Address of another Object. Must be non-NULL. * "match" * Boolean value representing the desired comparison result. * "plContext" * Platform-specific context pointer. * THREAD SAFETY: * Thread Safe (see Thread Safety Definitions in Programmer's Guide) * RETURNS: * Returns nothing. */ void testEqualsHelper( PKIX_PL_Object *goodObject, PKIX_PL_Object *otherObject, PKIX_Boolean match, void *plContext) { PKIX_Boolean cmpResult; PKIX_TEST_STD_VARS(); PKIX_TEST_EXPECT_NO_ERROR (PKIX_PL_Object_Equals (goodObject, otherObject, &cmpResult, plContext)); if ((match && !cmpResult) || (!match && cmpResult)){ testError("unexpected mismatch"); (void) printf("Actual value:\t%d\n", cmpResult); (void) printf("Expected value:\t%d\n", match); } cleanup: PKIX_TEST_RETURN(); } /* * FUNCTION: testDuplicateHelper * DESCRIPTION: * Checks if the Object pointed to by "object" is equal to its duplicate. * If the result of the check is not equality, an error message is generated. * PARAMETERS: * "object" * Address of Object. Must be non-NULL. * "plContext" * Platform-specific context pointer. * THREAD SAFETY: * Thread Safe (see Thread Safety Definitions in Programmer's Guide) * RETURNS: * Returns nothing. */ void testDuplicateHelper(PKIX_PL_Object *object, void *plContext) { PKIX_PL_Object *newObject = NULL; PKIX_Boolean cmpResult; PKIX_TEST_STD_VARS(); PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Duplicate (object, &newObject, plContext)); PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Equals (object, newObject, &cmpResult, plContext)); if (!cmpResult){ testError("unexpected mismatch"); (void) printf("Actual value:\t%d\n", cmpResult); (void) printf("Expected value:\t%d\n", PKIX_TRUE); } cleanup: PKIX_TEST_DECREF_AC(newObject); PKIX_TEST_RETURN(); }