/* * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved. * * The contents of this file constitute Original Code as defined in and are * subject to the Apple Public Source License Version 1.2 (the 'License'). * You may not use this file except in compliance with the License. Please obtain * a copy of the License at http://www.apple.com/publicsource and read it before * using this file. * * This Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the * specific language governing rights and limitations under the License. */ /* * c_examples/test_lib/test_lib.c * * uses SBufs for buffers * * MS 92 * * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/c-examples/test-lib/test-lib.c,v 1.1.1.1 2001/05/18 23:14:07 mb Exp $ * $Log: test-lib.c,v $ * Revision 1.1.1.1 2001/05/18 23:14:07 mb * Move from private repository to open source repository * * Revision 1.2 2001/05/05 00:59:20 rmurphy * Adding darwin license headers * * Revision 1.1.1.1 1999/03/16 18:06:09 aram * Originals from SMIME Free Library. * * Revision 1.5 1995/07/24 20:50:34 rj * ``#error "..."'' instead of ``#error ...''. * * changed `_' to `-' in file names. * * Revision 1.4 1995/02/18 16:17:44 rj * utilize either isinf(3) or finite(3), whatever happens to be present. * * Revision 1.3 1994/08/31 23:48:45 rj * more portable .h file inclusion. * * Revision 1.2 1994/08/31 08:59:39 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #include #include "asn-incl.h" int TestAsnBuffers(); int TestAsnTag(); int TestAsnLen(); int TestAsnBool(); int TestAsnInt(); int TestAsnReal(); int TestAsnOcts(); int TestAsnBits(); int TestAsnOid(); int TestAsnList(); int bufSize = 256; int main() { int isErr = FALSE; /* set up the PLUS and MINUS INFINITY globals */ InitAsnInfinity(); /* needed for OCTET STRING, BIT STRING and OBJECT IDENTIFIER decoding */ InitNibbleMem (256, 256); if (!TestAsnBuffers()) { fprintf (stdout, "Failed buffer tests, no point in proceeding ... bye!\n"); return 1; } if (!TestAsnTag()) { fprintf (stdout, "Failed Tag test.\n" ); isErr = TRUE; } if (!TestAsnLen()) { fprintf (stdout, "Failed Length test.\n" ); isErr = TRUE; } if (!TestAsnBool()) { fprintf (stdout, "Failed BOOLEAN test.\n" ); isErr = TRUE; } if (!TestAsnInt()) { fprintf (stdout, "Failed INTEGER test.\n" ); isErr = TRUE; } if (!TestAsnOcts()) { fprintf (stdout, "Failed OCTET STRING test.\n" ); isErr = TRUE; } if (!TestAsnBits()) { fprintf (stdout, "Failed BIT STRING test.\n" ); isErr = TRUE; } if (!TestAsnOid()) { fprintf (stdout, "Failed OBJECT IDENTIFIER test.\n" ); isErr = TRUE; } if (!TestAsnReal()) { fprintf (stdout, "Failed REAL test.\n" ); isErr = TRUE; } if (isErr) { fprintf (stdout, "There are errors in the primitive type encoding/decoding\n" ); fprintf (stdout, "library for this architecture. Time for gdb...\n" ); } else { fprintf (stdout, "The primitive type encoding/decoding library passed simple tests.\n"); fprintf (stdout, "It should be safe to use...\n" ); } return isErr; } /* * returns TRUE if passes encode/decode tests */ int TestAsnBuffers() { int i,j; int noErr = TRUE; SBuf b; char bufData[256]; /* initialize buffer */ SBufInit (&b, bufData, 256); SBufResetInWriteRvsMode (&b); /* * write whole range of byte (0..255) * remember, write works in reverse */ for (i = 0; i < 256; i++) BufPutByteRvs (&b,i); if (BufWriteError (&b)) { fprintf (stdout, "Error writing to buffer.\n" ); noErr = FALSE; } /* read in values & verify */ SBufResetInReadMode (&b); for (i = 255; i >= 0; i--) if (BufGetByte (&b) != i) { fprintf (stdout, "Error verifying data written to buffer.\n" ); noErr = FALSE; } if (BufReadError (&b)) { fprintf (stdout, "Error reading from buffer.\n" ); noErr = FALSE; } /* now make sure errors are detected */ SBufResetInWriteRvsMode (&b); for (i = 0; i < 257; i++) /* write past end of buffer */ BufPutByteRvs (&b,0); if (!BufWriteError (&b)) { fprintf (stdout, "Buffers failed to report buffer write overflow.\n" ); noErr = FALSE; } SBufResetInReadMode (&b); for (i = 256; i >= 0; i--) /* read past end of buffer */ BufGetByte (&b); if (!BufReadError (&b)) { fprintf (stdout, "Buffers failed to report buffer read overflow.\n" ); noErr = FALSE; } return noErr; } /* TestAsnBuffers */ /* * returns TRUE if passes encode/decode tests */ int TestAsnTag() { AsnTag aTag1; AsnTag aTag2; int i, j; AsnLen len1; AsnLen len2; AsnTag tag; int noErr = TRUE; ENV_TYPE env; SBuf b; char bufData[256]; long int val; BER_CLASS class; BER_FORM form; BER_UNIV_CODE code; /* initialize buffer */ SBufInit (&b, bufData, 256); /* encode a true value and verify */ class = UNIV; form = PRIM; code = INTEGER_TAG_CODE; aTag1 = MAKE_TAG_ID (class, form, code); for (i = 0; i < 2; i++) { SBufResetInWriteRvsMode (&b); len1 = BEncTag1 (&b, class, form, code); if (BufWriteError (&b)) { noErr = FALSE; fprintf (stdout, "Error encoding a Tag.\n" ); } SBufResetInReadMode (&b); aTag2 = 0; /* make sure no decode errors and that it decodes to same tag */ len2 = 0; if ((val = setjmp (env)) == 0) { aTag2 = BDecTag (&b, &len2, env); } else { noErr = FALSE; fprintf (stdout, "Error decoding a Tag - error number %d\n", val); } if (noErr && ((aTag2 != aTag1) || (len1 != len2))) { noErr = FALSE; fprintf (stdout, "Error decoded Tag does not match encoded Tag.\n" ); } /* set a new test tag value */ class = CNTX; form = CONS; code = 29; aTag1 = MAKE_TAG_ID (class, form, code); } return noErr; } /* TestAsnTag */ /* * returns TRUE if passes encode/decode tests */ int TestAsnLen() { AsnLen aLen1; AsnLen aLen2; int i,j; AsnLen len1; AsnLen len2; AsnTag tag; int noErr = TRUE; ENV_TYPE env; SBuf b; char bufData[256]; long int val; /* initialize buffer */ SBufInit (&b, bufData, 256); /* encode a true value and verify */ aLen1 = 99999; for (i = 0; i < 2; i++) { SBufResetInWriteRvsMode (&b); len1 = BEncDefLen (&b, aLen1); if (BufWriteError (&b)) { noErr = FALSE; fprintf (stdout, "Error encoding Length.\n" ); } SBufResetInReadMode (&b); aLen2 = 0; /* make sure no decode errors and that it decodes to true */ len2 = 0; if ((val = setjmp (env)) == 0) { aLen2 = BDecLen (&b, &len2, env); } else { noErr = FALSE; fprintf (stdout, "Error decoding Length - error number %d\n", val); } if (noErr && ((aLen2 != aLen1) || (len1 != len2))) { noErr = FALSE; fprintf (stdout, "Error - decoded lenght does not match encoded length\n"); } aLen1 = 2; } /* test indef len */ SBufResetInWriteRvsMode (&b); len1 = BEncIndefLen (&b); if (BufWriteError (&b)) { noErr = FALSE; fprintf (stdout, "Error encoding indefinite Length.\n" ); } SBufResetInReadMode (&b); aLen2 = 0; /* make sure no decode errors */ len2 = 0; if ((val = setjmp (env)) == 0) { aLen2 = BDecLen (&b, &len2, env); } else { noErr = FALSE; fprintf (stdout, "Error decoding Length - error number %d\n", val); } if (noErr && ((aLen2 != INDEFINITE_LEN) || (len1 != len2))) { noErr = FALSE; fprintf (stdout, "Error - decoded length does not match encoded length\n"); } /* test EOC */ SBufResetInWriteRvsMode (&b); len1 = BEncEoc (&b); if (BufWriteError (&b)) { noErr = FALSE; fprintf (stdout, "Error encoding indefinite Length.\n" ); } SBufResetInReadMode (&b); aLen2 = 0; /* make sure no decode errors */ len2 = 0; if ((val = setjmp (env)) == 0) { BDecEoc (&b, &len2, env); } else { noErr = FALSE; fprintf (stdout, "Error decoding Length - error number %d\n", val); } if (noErr && (len1 != len2)) { noErr = FALSE; fprintf (stdout, "Error - decoded EOC length error.\n"); } return noErr; } /* TestAsnLen */ /* * returns TRUE if passes encode/decode tests */ int TestAsnBool() { AsnBool aBool1; AsnBool aBool2; int j; AsnLen len1; AsnLen len2; AsnTag tag; int noErr = TRUE; ENV_TYPE env; SBuf b; char bufData[256]; long int val; /* initialize buffer */ SBufInit (&b, bufData, 256); SBufResetInWriteRvsMode (&b); /* encode a true value and verify */ aBool1 = TRUE; len1 = BEncAsnBoolContent (&b, &aBool1); if (BufWriteError (&b)) { noErr = FALSE; fprintf (stdout, "Error encoding TRUE BOOLEAN value.\n" ); } SBufResetInReadMode (&b); aBool2 = FALSE; /* set to opposite of expected value */ /* make sure no decode errors and that it decodes to true */ len2 = 0; if ((val = setjmp (env)) == 0) { BDecAsnBoolContent (&b, tag, len1, &aBool2, &len2, env); } else { noErr = FALSE; fprintf (stdout, "Error decoding a BOOLEAN - error number %d\n", val); } if (noErr && ((aBool2 != aBool1) || (len1 != len2))) { noErr = FALSE; fprintf (stdout, "Error decoding TRUE BOOLEAN value.\n" ); } /* now encode a false value and verify */ SBufResetInWriteRvsMode (&b); aBool1 = FALSE; len1 = BEncAsnBoolContent (&b, &aBool1); if (BufWriteError (&b)) { noErr = FALSE; fprintf (stdout, "Error encoding FALSE BOOLEAN value.\n" ); } SBufResetInReadMode (&b); aBool2 = TRUE; /* set to opposite of expected value */ /* make sure no decode errors and that it decodes to true */ len2 = 0; if ((val = setjmp (env)) == 0) { BDecAsnBoolContent (&b, tag, len1, &aBool2, &len2, env); } else { noErr = FALSE; fprintf (stdout, "Error decoding a BOOLEAN - error number %d\n", val); } if (noErr && ((aBool2 != aBool1) || (len1 != len2))) { noErr = FALSE; fprintf (stdout, "Error decoding TRUE BOOLEAN value.\n" ); } /* make sure no decode errors and that it decodes to false */ return noErr; } /* TestAsnBool */ /* * returns TRUE if passes encode/decode tests */ int TestAsnInt() { AsnInt a1; AsnInt a2; int i,j; AsnLen len1; AsnLen len2; AsnTag tag; int noErr = TRUE; ENV_TYPE env; SBuf b; char bufData[256]; long int val; int sign; /* initialize buffer */ SBufInit (&b, bufData, 256); /* * Encode a range of integers: negative & positive in * the 1 to sizeof (AsnInt) range */ sign = 1; for (j = 0; j < 2; j++) { for (i = 0; i < sizeof (AsnInt); i++) { SBufResetInWriteRvsMode (&b); a1 = sign * (17 << (i * 8)); /* 17 is a random choice :) */ len1 = BEncAsnIntContent (&b, &a1); if (BufWriteError (&b)) { noErr = FALSE; fprintf (stdout, "Error encoding INTEGER value %d.\n", a1 ); } SBufResetInReadMode (&b); /* make sure no decode errors and that it decodes to true */ len2 = 0; if ((val = setjmp (env)) == 0) { BDecAsnIntContent (&b, tag, len1, &a2, &len2, env); } else { noErr = FALSE; fprintf (stdout, "Error decoding a INTEGER - error number %d\n", val); } if (noErr && ((a2 != a1) || (len1 != len2))) { noErr = FALSE; fprintf (stdout, "Error decoding INTEGER value %d.\n", a1 ); } } sign = -1; } return noErr; } /* TestAsnInt */ /* * returns TRUE if passes encode/decode tests */ int TestAsnOcts() { AsnOcts a1; AsnOcts a2; int i,j; AsnLen len1; AsnLen len2; AsnTag tag; int noErr = TRUE; ENV_TYPE env; SBuf b; char bufData[256]; long int val; /* initialize buffer */ SBufInit (&b, bufData, 256); a1.octs = "Hello Gumby"; a1.octetLen = strlen (a1.octs); /* * octet string decoder needs to know tag form * (snacc always encodes octet strings as primitives) */ tag = MAKE_TAG_ID (UNIV, PRIM, OCTETSTRING_TAG_CODE); for (j = 0; j < 2; j++) { SBufResetInWriteRvsMode (&b); len1 = BEncAsnOctsContent (&b, &a1); if (BufWriteError (&b)) { noErr = FALSE; fprintf (stdout, "Error encoding OCTET STRING value \"%s\".\n", a1.octs ); } SBufResetInReadMode (&b); /* make sure no decode errors and that it decodes to true */ len2 = 0; if ((val = setjmp (env)) == 0) { BDecAsnOctsContent (&b, tag, len1, &a2, &len2, env); } else { noErr = FALSE; fprintf (stdout, "Error decoding an OCTET STRING - error number %d\n", val); } if (noErr && (!AsnOctsEquiv (&a2,&a1) || (len1 != len2))) { noErr = FALSE; fprintf (stdout, "Error decoding OCTET STRING value %s.\n", a1.octs ); } a1.octs = ""; /* test empty string */ a1.octetLen = strlen (a1.octs); } ResetNibbleMem(); return noErr; } /* TestAsnOcts */ /* * returns TRUE if passes encode/decode tests */ int TestAsnBits() { AsnBits a1; AsnBits a2; int i,j; AsnLen len1; AsnLen len2; AsnTag tag; int noErr = TRUE; ENV_TYPE env; SBuf b; char bufData[256]; long int val; short bitsToSet[35]; /* * init bitsToSet - old compilers don't support automatic init * of aggregate types. */ bitsToSet[0] = 0; bitsToSet[1] = 1; bitsToSet[2] = 0; bitsToSet[3] = 0; bitsToSet[4] = 1; bitsToSet[5] = 1; bitsToSet[6] = 0; bitsToSet[7] = 1; bitsToSet[8] = 0; bitsToSet[9] = 1; bitsToSet[10] = 0; bitsToSet[11] = 0; bitsToSet[12] = 1; bitsToSet[13] = 1; bitsToSet[14] = 0; bitsToSet[15] = 1; bitsToSet[16] = 0; bitsToSet[17] = 1; bitsToSet[18] = 0; bitsToSet[19] = 0; bitsToSet[20] = 1; bitsToSet[21] = 1; bitsToSet[22] = 0; bitsToSet[23] = 1; bitsToSet[24] = 0; bitsToSet[25] = 1; bitsToSet[26] = 0; bitsToSet[27] = 1; bitsToSet[28] = 1; bitsToSet[29] = 0; bitsToSet[30] = 1; bitsToSet[31] = 1; bitsToSet[32] = 0; bitsToSet[33] = 1; bitsToSet[34] = 0; /* initialize buffer */ SBufInit (&b, bufData, 256); /* initialize bit string */ a1.bits = Asn1Alloc (5); a1.bitLen = 35; for (i = 0; i < 35; i++) { if (bitsToSet[i]) SetAsnBit (&a1, i); else ClrAsnBit (&a1, i); } /* * bit string decoder needs to know tag form * (snacc always encodes bit strings as primitives) */ tag = MAKE_TAG_ID (UNIV, PRIM, BITSTRING_TAG_CODE); SBufResetInWriteRvsMode (&b); len1 = BEncAsnBitsContent (&b, &a1); if (BufWriteError (&b)) { noErr = FALSE; fprintf (stdout, "Error encoding BIT STRING value "); PrintAsnBits (stdout, &a1, 0); fprintf (stdout, "\n"); } SBufResetInReadMode (&b); /* make sure no decode errors and that it decodes to true */ len2 = 0; if ((val = setjmp (env)) == 0) { BDecAsnBitsContent (&b, tag, len1, &a2, &len2, env); } else { noErr = FALSE; fprintf (stdout, "Error decoding an BIT STRING - error number %d\n", val); } if (noErr && (!AsnBitsEquiv (&a2,&a1) || (len1 != len2))) { noErr = FALSE; fprintf (stdout, "Error decoding BIT STRING value "); PrintAsnBits (stdout, &a1, 0); fprintf (stdout, "\n"); } ResetNibbleMem(); return noErr; } /* TestAsnBits */ /* * returns TRUE if passes encode/decode tests */ int TestAsnOid() { AsnOid a1; AsnOid a2; int i,j; AsnLen len1; AsnLen len2; AsnTag tag; int noErr = TRUE; ENV_TYPE env; SBuf b; char bufData[256]; long int val; /* initialize buffer */ SBufInit (&b, bufData, 256); /* mib-2 oid { iso 3 6 1 2 1 }*/ a1.octetLen = 5; a1.octs = "\53\6\1\2\1"; for (j = 0; j < 2; j++) { SBufResetInWriteRvsMode (&b); len1 = BEncAsnOidContent (&b, &a1); if (BufWriteError (&b)) { noErr = FALSE; fprintf (stdout, "Error encoding OCTET STRING value \"%s\".\n", a1.octs ); } SBufResetInReadMode (&b); /* make sure no decode errors and that it decodes to true */ len2 = 0; if ((val = setjmp (env)) == 0) { BDecAsnOidContent (&b, tag, len1, &a2, &len2, env); } else { noErr = FALSE; fprintf (stdout, "Error decoding an OCTET STRING - error number %d\n", val); } if (noErr && (!AsnOidsEquiv (&a2,&a1) || (len1 != len2))) { noErr = FALSE; fprintf (stdout, "Error decoding OCTET STRING value %s.\n", a1.octs ); } /* system { mib-2 1 }*/ a1.octs = "\53\6\1\2\1\1"; a1.octetLen = 6; } ResetNibbleMem(); return noErr; } /* TestAsnOid */ /* * returns TRUE if passes encode/decode tests */ int TestAsnReal() { AsnReal a1[5]; AsnReal a2; int i,j; AsnLen len1; AsnLen len2; AsnTag tag; int noErr = TRUE; int elmtErr = FALSE; ENV_TYPE env; SBuf b; char bufData[256]; long int val; int sign; AsnReal inf; unsigned char *c; /* * if you do not have the ieee_functions in your math lib, * this will not link. Comment it out and cross you fingers. * (or check/set the +/-infinity values for you architecture) */ #if HAVE_ISINF if (!isinf (PLUS_INFINITY) || !isinf (MINUS_INFINITY)) #else #if HAVE_FINITE if (finite (PLUS_INFINITY) || finite (MINUS_INFINITY)) #else #error "oops: you've got neither isinf(3) nor finite(3)?!" #endif #endif { fprintf (stdout, "WARNING: PLUS_INFINITY and MINUS_INFINITY in asn_real.c are not\n"); fprintf (stdout, "correct for this architecture. Modify the InitAsnInfinity() Routine.\n"); } /* * init test value array. * some old compilers don't support automatic init of aggregate types * like: * AsnReal a1[] = { 0.0, 0.8, -22.484848, PLUS_INFINITY, MINUS_INFINITY}; */ a1[0] = 0.0; a1[1] = 0.8; a1[2] = -22.484848; a1[3] = PLUS_INFINITY; a1[4] = MINUS_INFINITY; /* initialize buffer */ SBufInit (&b, bufData, 256); /* * Encode a range of integers: negative & positive in * the 1 to sizeof (AsnInt) range */ for (i = 0; i < 5; i++) { elmtErr = FALSE; SBufResetInWriteRvsMode (&b); len1 = BEncAsnRealContent (&b, &a1[i]); if (BufWriteError (&b)) { elmtErr = TRUE; fprintf (stdout, "Error encoding REAL value "); PrintAsnReal (stdout,&a1[i],0); fprintf (stdout, ".\n"); } SBufResetInReadMode (&b); /* make sure no decode errors and that it decodes to true */ len2 = 0; if ((val = setjmp (env)) == 0) { BDecAsnRealContent (&b, tag, len1, &a2, &len2, env); } else { elmtErr = TRUE; fprintf (stdout, "Error decoding a REAL - error number %d\n", val); } /* testing reals for equality is sketchy */ if (!elmtErr && ((a2 != a1[i]) || (len1 != len2))) { elmtErr = TRUE; fprintf (stdout, "Error decoding REAL value "); PrintAsnReal (stdout, &a1[i], 0); fprintf (stdout, ".\n"); if (len1 == len2) /* therefore a2 != a1[i] */ { fprintf (stdout, "The value decoded was "); PrintAsnReal (stdout, &a2, 0); fprintf (stdout, ".\n"); } else fprintf (stdout, "The encoded and decoded length disagree.\n"); } if (elmtErr) noErr = FALSE; } return noErr; } /* TestAsnReal */